some cleaning and /search/

Signed-off-by: Maxence Lange <maxence@artificial-owl.com>
This commit is contained in:
Maxence Lange 2021-03-08 11:32:18 -01:00
parent 71d0aaf87f
commit b660360446
28 changed files with 254 additions and 3605 deletions

View file

@ -68,7 +68,7 @@ Users won't be able to find this Circle using Nextcloud search engine.
<command>OCA\Circles\Command\CirclesList</command>
<command>OCA\Circles\Command\CirclesRemote</command>
<command>OCA\Circles\Command\MembersList</command>
<command>OCA\Circles\Command\MembersSearch</command>
<command>OCA\Circles\Command\CirclesMemberships</command>

View file

@ -28,6 +28,7 @@ return [
'ocs' => [
['name' => 'Local#circles', 'url' => '/circles/', 'verb' => 'GET'],
['name' => 'Local#create', 'url' => '/circles/', 'verb' => 'POST'],
['name' => 'Local#search', 'url' => '/search/', 'verb' => 'POST'],
['name' => 'Local#members', 'url' => '/circles/{circleId}/members/', 'verb' => 'GET'],
['name' => 'Local#memberAdd', 'url' => '/circles/{circleId}/members/', 'verb' => 'POST'],
[

View file

@ -1,13 +0,0 @@
#circles input[type='checkbox'].checkbox + label {
padding: 12px 0;
display: inline-block;
}
#circles input[type='checkbox'].checkbox + label:before {
margin-right: 12px;
}
#circles em {
display: block;
margin-top: -10px;
}

View file

@ -1,373 +0,0 @@
#loading_members {
height: 50px;
margin: 0 auto;
padding: 20px;
}
#circle-navigation .navigation-element, #circle-navigation .navigation-element option {
padding: 3px 12px;
}
#circle-navigation input#circles_search, #circle-navigation select#circles_filters {
margin: 10px;
width: 225px;
}
#circle-navigation select#circles_filters {
margin-top: 0;
font-style: italic;
color: #777777;
}
#circle-navigation input, #circle-navigation select, #circle-navigation option {
width: 100%;
box-sizing: border-box;
background: #ffffffaa !important;
}
#app-content {
overflow-x: hidden;
position: absolute !important;
left: 543px;
right: 0px;
height: 100%;
top: 50px;
}
#circle-navigation .header {
padding: 0 12px;
line-height: 44px;
min-height: 44px;
border-bottom: 1px solid #eee;
}
#circles_new_type_definition div {
margin-top: 10px;
position: absolute;
width: 250px;
color: #474747b0;
word-wrap: break-word;
}
SELECT.select_none {
font-style: italic;
}
#circles_list, #circles_list .lightenbg {
position: absolute;
width: 100%;
top: 400px;
}
#circles_list div {
position: relative;
padding: 15px;
border-bottom: solid 1px #cccccc88;
color: #555;
cursor: pointer;
background: #f9f9f9;
-webkit-transition: background-color 0.3s ease-in;
transition: background-color 0.3s ease-in;
font-weight: normal;
}
#circles_list div:hover {
background: #f2f2f2;
}
#circles_list .selected {
background: #ededed !important;
font-weight: bold !important;
}
#circle-navigation {
width: 300px;
height: 100%;
border-right: 1px solid #ddd;
}
#circle-navigation.circles {
overflow-y: auto;
overflow-x: hidden;
z-index: 1002;
position: absolute;
left: 300px;
top: 50px;
bottom: 0;
width: 243px;
}
#circle-navigation.circles, #circle-navigation.circles .circle, #circle-navigation.circles .selected {
-webkit-transition: background-color 0.3s ease-in;
transition: background-color 0.3s ease-in;
}
#circle-navigation.selected {
background: #ededed !important;
}
#circle-navigation.circles .selected {
background: #e5e5e5;
}
/* circles */
.circle {
border-bottom: solid 1px #ddd;
border-radius: 2px;
padding: 2px;
padding-top: 12px;
padding-bottom: 12px;
}
.circle:hover {
background: #e9e9e9;
}
div.circle .title {
font-weight: bold;
font-size: 13px;
color: #333333dd;
margin-left: 10px;
font-style: italic;
}
div.circle .owner, div.circle .type, div.circle .resume {
margin-left: 20px;
font-size: 11px;
margin-bottom: -4px;
color: #2c2c2c99;
}
#mainui {
display: none;
}
#mainui #circle_details, #circle_details .lightenbg {
background-color: #0082c9;
width: 100%;
height: 105px;
}
#circle_details .lightenbg {
background: #ffffff99;
position: absolute;
}
#mainui #circle_details #name {
font-size: 30px;
padding: 10px;
color: #000000c0;
display: inline-block;
position: absolute;
}
#mainui #circle_details #type {
font-size: 16px;
top: 35px;
left: 20px;
position: absolute;
display: inline-block;
color: #00000090;
font-style: italic;
}
#circledata {
position: absolute !important;
overflow-y: auto;
bottom: 5px;
right: 10px;
left: 15px;
top: 120px;
overflow-x: hidden;
}
#circle_desc {
margin: 15px;
padding: 10px;
background: #f0f0f0
}
#mainui #memberslist {
position: absolute;
overflow-y: auto;
width: 100%;
overflow-x: hidden;
}
#memberslist_table, #linkslist_table, #groupslist_table {
width: 100%;
}
#mainui #memberslist .header td {
font-weight: bold;
padding: 10px;
}
#mainui #memberslist .entry td {
border-bottom: solid 1px #eee;
color: #555;
}
.members_search, .groups_search {
padding: 12px;
padding-top: 5px;
border-top: solid 1px #00000022;
-webkit-transition: background-color 0.2s ease-in;
transition: background-color 0.2s ease-in;
height: 65px;
}
.members_search:hover, .groups_search:hover {
background: #fafafa;
-webkit-transition: background-color 0.2s ease-in;
transition: background-color 0.2s ease-in;
}
.members_search.exact, .groups_search.exact {
background: #eee;
}
#emptycontent {
display: none;
position: absolute;
z-index: 1001;
left: 0px;
}
#circle-actions {
right: 10px;
position: absolute;
top: 20px;
}
#circle-actions button {
padding: 15px;
background-color: transparent;
border: none;
opacity: .5;
}
#circle-actions button:hover {
opacity: .9;
}
#circle-actions-return {
float: right;
margin-top: 6px;
}
#linkcircle, #addmember, #linkgroup, #joincircle, #leavecircle {
width: 350px;
}
#members_search_result > #addmember, #groups_search_result > #linkgroup {
position: relative;
width: 220px;
right: 20px;
top: 5px;
}
#members_search_result, #groups_search_result {
z-index: 5;
border-radius: 4px;
border: solid 1px #00000022;
color: #000000aa;
background: #ffffffdd;
max-height: 400px;
overflow-y: auto;
position: absolute;
top: 45px;
width: 360px;
}
.icon-add-user {
background-size: 16px;
}
.icon-link-group {
background-size: 16px;
}
.icon-join {
background-size: 16px;
opacity: .2;
float: right;
margin-top: 5px;
}
.level-select, .status-select {
border: 0;
margin: 0;
background: #fff0;
}
.link-status-select {
border: 0;
margin: 0;
background: #fff;
}
#mainui #settings-panel {
position: absolute;
bottom: 15px;
right: 15px;
left: 15px;
top: 120px;
overflow-y: auto;
}
#joincircle_request, #joincircle_invit {
display: inline-block;
padding: 10px;
color: #555;
}
#settings-table {
width: 100%;
color: #555;
}
#settings-table td.left {
font-weight: bold;
text-align: right;
width: 50%;
font-size: 15px;
padding: 15px 40px;
}
#settings-table .hint {
font-weight: normal;
font-size: 11px
}
#settings-name {
width: 300px;
}
#single-password {
width: 270px;
}
#settings-desc {
width: 300px;
height: 140px;
}
#settings-submit {
margin: 15px;
}
#adminsettingscircle {
position: absolute;
bottom: 1px;
left: 4px;
}
DIV.result_top {
font-size: 15px;
}
DIV.result_bot {
font-size: 12px;
height: 10px;
font-style: italic;
}

View file

@ -1,4 +0,0 @@
@-webkit-keyframes a{0%{opacity:0;bottom:-15px;max-height:0;max-width:0;margin-top:0}30%{opacity:.8;bottom:-3px}to{opacity:1;bottom:0;max-height:200px;margin-top:12px;max-width:400px}}@keyframes a{0%{opacity:0;bottom:-15px;max-height:0;max-width:0;margin-top:0}30%{opacity:.8;bottom:-3px}to{opacity:1;bottom:0;max-height:200px;margin-top:12px;max-width:400px}}@-webkit-keyframes b{0%{opacity:1;bottom:0}30%{opacity:.2;bottom:-3px}to{opacity:0;bottom:-15px}}@keyframes b{0%{opacity:1;bottom:0}30%{opacity:.2;bottom:-3px}to{opacity:0;bottom:-15px}}@-webkit-keyframes c{0%{opacity:0}30%{opacity:.5}to{opacity:.6}}@keyframes c{0%{opacity:0}30%{opacity:.5}to{opacity:.6}}@-webkit-keyframes d{0%{opacity:.6}30%{opacity:.1}to{opacity:0}}@keyframes d{0%{opacity:.6}30%{opacity:.1}to{opacity:0}}.notyf__icon--alert,.notyf__icon--confirm{height:21px;width:21px;background:#fff;border-radius:50%;display:block;margin:0 auto;position:relative}.notyf__icon--alert:after,.notyf__icon--alert:before{content:"";background:#ed3d3d;display:block;position:absolute;width:3px;border-radius:3px;left:9px}.notyf__icon--alert:after{height:3px;top:14px}.notyf__icon--alert:before{height:8px;top:4px}.notyf__icon--confirm:after,.notyf__icon--confirm:before{content:"";background:#3dc763;display:block;position:absolute;width:3px;border-radius:3px}.notyf__icon--confirm:after{height:6px;-webkit-transform:rotate(-45deg);transform:rotate(-45deg);top:9px;left:6px}.notyf__icon--confirm:before{height:11px;-webkit-transform:rotate(45deg);transform:rotate(45deg);top:5px;left:10px}.notyf__toast{display:block;overflow:hidden;-webkit-animation:a .3s forwards;animation:a .3s forwards;box-shadow:0 1px 3px 0 rgba(0,0,0,.45);position:relative;padding-right:13px}.notyf__toast.notyf--alert{background:#ed3d3d}.notyf__toast.notyf--confirm{background:#3dc763}.notyf__toast.notyf--disappear{-webkit-animation:b .3s 1 forwards;animation:b .3s 1 forwards;-webkit-animation-delay:.25s;animation-delay:.25s}.notyf__toast.notyf--disappear .notyf__message{opacity:1;-webkit-animation:b .3s 1 forwards;animation:b .3s 1 forwards;-webkit-animation-delay:.1s;animation-delay:.1s}.notyf__toast.notyf--disappear .notyf__icon{opacity:1;-webkit-animation:d .3s 1 forwards;animation:d .3s 1 forwards}.notyf__wrapper{display:table;width:100%;padding-top:20px;padding-bottom:20px;padding-right:15px;border-radius:3px}.notyf__icon{width:20%;text-align:center;font-size:1.3em;-webkit-animation:c .5s forwards;animation:c .5s forwards;-webkit-animation-delay:.25s;animation-delay:.25s}.notyf__icon,.notyf__message{display:table-cell;vertical-align:middle;opacity:0}.notyf__message{width:80%;position:relative;-webkit-animation:a .3s forwards;animation:a .3s forwards;-webkit-animation-delay:.15s;animation-delay:.15s}.notyf{position:fixed;bottom:20px;right:30px;width:20%;color:#fff;z-index:1}@media only screen and (max-width:736px){.notyf__container{width:90%;margin:0 auto;display:block;right:0;left:0}}
.notyf {
z-index: 1001;
}

View file

@ -1,190 +0,0 @@
/*
* Circles - Bring cloud-users closer together.
*
* This file is licensed under the Affero General Public License version 3 or
* later. See the COPYING file.
*
* @author Maxence Lange <maxence@pontapreta.net>
* @copyright 2017
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
/** global: OC */
var elements = {
test_timer: 4000,
// test_async_start: null,
// test_async_reset: null,
// test_async_wait: null,
members_limit: null,
allow_linked_groups: null,
skip_invitation_to_closed_circles: null
};
$(document).ready(function() {
// elements.test_async_start = $('#test_async_start');
// elements.test_async_reset = $('#test_async_reset');
// elements.test_async_wait = $('#test_async_wait');
// elements.test_async_result = $('#test_async_result');
elements.members_limit = $('#members_limit');
elements.allow_linked_groups = $('#allow_linked_groups');
elements.skip_invitation_to_closed_circles = $('#skip_invitation_to_closed_circles');
// elements.test_async_wait.hide().on('click', function () {
// self.refreshResult();
// });
//
// elements.test_async_reset.hide().on('click', function () {
// $.ajax({
// method: 'DELETE',
// url: OC.generateUrl('/apps/circles/admin/testAsync')
// }).done(function (res) {
// self.displayTestAsync(res);
// });
// });
//
// elements.test_async_start.hide().on('click', function () {
// $.ajax({
// method: 'POST',
// url: OC.generateUrl('/apps/circles/admin/testAsync')
// }).done(function (res) {
// self.displayTestAsync(res);
// });
// });
elements.members_limit.on('change', function() {
saveChange();
});
elements.allow_linked_groups.on('change', function() {
saveChange();
});
elements.skip_invitation_to_closed_circles.on('change', function() {
saveChange();
});
saveChange = function() {
$.ajax({
method: 'POST',
url: OC.generateUrl('/apps/circles/admin/settings'),
data: {
members_limit: elements.members_limit.val(),
allow_linked_groups: (elements.allow_linked_groups.is(
':checked')) ? '1' : '0',
skip_invitation_to_closed_circles: (elements.skip_invitation_to_closed_circles.is(
':checked')) ? '1' : '0'
}
}).done(function(res) {
elements.members_limit.val(res.membersLimit);
elements.allow_linked_groups.prop('checked', (res.allowLinkedGroups === '1'));
elements.skip_invitation_to_closed_circles.prop('checked', (res.skipInvitationStep === '1'));
});
};
updateTestAsync = function() {
self.refreshResult();
};
refreshResult = function() {
$.ajax({
method: 'GET',
url: OC.generateUrl('/apps/circles/admin/testAsync')
}).done(function(res) {
self.displayTestAsync(res);
});
};
displayTestAsync = function(res) {
// displayTestAsyncResult(res);
// displayTestAsyncNewTest(res);
// displayTestAsyncReset(res);
// displayTestAsyncWait(res);
};
// displayTestAsyncResult = function (res) {
// if (res.init !== '0') {
// if (res.test.running === 0) {
// elements.test_async_result.text(
// 'Test is now over; final score: ' + res.test.note);
// return;
// }
//
//
// elements.test_async_result.text(
// 'Test is running. current tick: ' + res.count + '/121');
//
// return;
// }
//
// elements.test_async_result.text(
// t('circles', 'Circles uses its own method to async heavy processes.'));
// };
//
//
// displayTestAsyncNewTest = function (res) {
// if (res.init !== '' && res.init !== '0') {
// elements.test_async_start.hide();
// return;
// }
//
// elements.test_async_start.show();
// };
//
// displayTestAsyncReset = function (res) {
// if (res.init !== '' && res.init !== '0') {
// elements.test_async_reset.show();
// return;
// }
//
// elements.test_async_reset.hide();
// };
//
// displayTestAsyncWait = function (res) {
// if (Number(res.test.running) === 1) {
// elements.test_async_reset.hide();
// elements.test_async_start.hide();
// elements.test_async_wait.show();
// return;
// }
//
// elements.test_async_wait.hide();
// };
$.ajax({
method: 'GET',
url: OC.generateUrl('/apps/circles/admin/settings'),
data: {}
}).done(function(res) {
elements.members_limit.val(res.membersLimit);
elements.allow_linked_groups.prop('checked', (res.allowLinkedGroups === '1'));
elements.skip_invitation_to_closed_circles.prop('checked', (res.skipInvitationStep === '1'));
});
//
// var timerTestAsync = setInterval(function () {
// self.updateTestAsync();
// }, elements.test_timer);
})
;

View file

@ -1,235 +0,0 @@
/*
* Circles - Bring cloud-users closer together.
*
* This file is licensed under the Affero General Public License version 3 or
* later. See the COPYING file.
*
* @author Maxence Lange <maxence@pontapreta.net>
* @copyright 2017
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
/** global: OC */
/** global: OCA */
/** global: Notyf */
/** global: actions */
/** global: nav */
/** global: elements */
/** global: resultMembers */
/** global: resultGroups */
/** global: resultCircles */
/** global: curr */
/** global: api */
/** global: define */
/** global: resultLinks */
/** global: settings */
var actions = {
changeMemberLevel: function(member, type, instance, level) {
if (Number(level) === define.levelOwner) {
actions.changeMemberOwner(member, type, instance);
return;
}
api.levelMember(curr.circle, member, type, instance, level, resultMembers.levelMemberResult);
nav.circlesActionReturn();
},
changeGroupLevel: function(group, level) {
if (level === 'remove_group') {
api.unlinkGroup(curr.circle, group, resultGroups.unlinkGroupResult);
} else {
api.levelGroup(curr.circle, group, level, resultGroups.levelGroupResult);
}
nav.circlesActionReturn();
},
changeMemberOwner: function(member, type, instance) {
OC.dialogs.confirm(
t('circles', 'Are you sure you want to transfer your ownership?', [member]),
t('circles', 'This action is irreversible'),
function(e) {
if (e === true) {
api.levelMember(curr.circle, member, type, instance, define.levelOwner,
resultMembers.levelMemberResult);
nav.circlesActionReturn();
return;
}
nav.displayMembers('');
});
},
changeMemberStatus: function(member, type, instance, value) {
if (value === 'remove_member' || value === 'dismiss_request') {
api.removeMember(curr.circle, member, type, instance, resultMembers.removeMemberResult);
}
if (value === 'accept_request') {
api.addMember(curr.circle, member, type, instance, resultMembers.addMemberResult);
}
},
changeLinkStatus: function(link, value) {
api.linkStatus(link, value, resultLinks.linkStatusResult);
},
validateEmail: function(email) {
var re = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
return re.test(email);
},
selectCircle: function(circle_id) {
curr.searchUser = '';
elements.addMember.val('');
elements.linkGroup.val('');
elements.linkCircle.val('');
nav.circlesActionReturn();
api.detailsCircle(circle_id, resultCircles.selectCircleResult);
},
unselectCircle: function(circle_id) {
elements.mainUIMembersTable.emptyTable();
elements.navigation.children(".circle[circle-id='" + circle_id + "']").remove();
elements.emptyContent.show(400);
elements.mainUI.fadeOut(400);
curr.circle = 0;
curr.circleLevel = 0;
},
saveSettings: function() {
let data = {
circle_name: elements.settingsName.val(),
circle_desc: elements.settingsDesc.val(),
allow_links: (elements.settingsLink.is(":checked")),
password_enforcement: (elements.settingsPassword.is(":checked")),
password_single_enabled: (elements.settingsSinglePasswordEnabled.is(":checked")),
password_single: elements.settingsSinglePassword.val(),
members_limit: elements.settingsLimit.val(),
allow_links_auto: (elements.settingsLinkAuto.is(":checked")),
allow_links_files: (elements.settingsLinkFiles.is(":checked"))
};
console.log(JSON.stringify(data));
api.settingsCircle(curr.circle, data, settings.saveSettingsResult);
},
/**
*
* @param search
*/
searchMembersRequest: function(search) {
if (curr.searchUser === search) {
return;
}
curr.searchUser = search;
api.searchUsers(search, resultMembers.searchMembersResult);
},
/**
*
* @param search
*/
searchGroupsRequest: function(search) {
if (curr.searchGroup === search) {
return;
}
curr.searchGroup = search;
$.get(OC.linkToOCS('apps/files_sharing/api/v1', 1) + 'sharees',
{
format: 'json',
search: search,
perPage: 200,
itemType: 'principals'
}, resultGroups.searchGroupsResult);
},
getStringTypeFromType: function(type) {
switch (Number(type)) {
case define.typePersonal:
return t('circles', 'Personal circle');
case define.typeSecret:
return t('circles', 'Secret circle');
case define.typeClosed:
return t('circles', 'Closed circle');
case define.typePublic:
return t('circles', 'Public circle');
}
return t('circles', 'Circle');
},
/**
*
*/
onEventNewCircle: function() {
curr.circle = 0;
curr.circleLevel = 0;
elements.circlesList.children('div').removeClass('selected');
elements.emptyContent.show(400);
elements.mainUI.fadeOut(400);
},
/**
*
*/
onEventNewCircleName: function() {
this.onEventNewCircle();
nav.displayOptionsNewCircle((elements.newName.val() !== ''));
},
/**
*
*/
onEventNewCircleType: function() {
this.onEventNewCircle();
elements.newTypeDefinition.children('div').fadeOut(300);
var selectedType = elements.newType.children('option:selected').val();
if (selectedType === '') {
elements.newType.addClass('select_none');
} else {
elements.newType.removeClass('select_none');
$('#circles_new_type_' + selectedType).fadeIn(
300);
}
}
};

View file

@ -1,497 +0,0 @@
/*
* Circles - Bring cloud-users closer together.
*
* This file is licensed under the Affero General Public License version 3 or
* later. See the COPYING file.
*
* @author Maxence Lange <maxence@pontapreta.net>
* @copyright 2017
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
/** global: OC */
/** global: OCA */
/** global: Notyf */
/** global: nav */
/** global: actions */
/** global: settings */
/** global: resultCircles */
/** global: curr */
/** global: api */
/** global: define */
var elements = {
newTypeDefinition: null,
newType: null,
newSubmit: null,
newName: null,
navigation: null,
circlesList: null,
circlesSearch: null,
circlesFilters: null,
circleDetails: null,
circleDesc: null,
emptyContent: null,
mainUI: null,
mainUIMembersTable: null,
mainUIGroupsTable: null,
mainUILinksTable: null,
membersSearchResult: null,
groupsSearchResult: null,
memberDetails: null,
memberRequest: null,
joinCircleInteraction: null,
joinCircleAccept: null,
joinCircleReject: null,
joinCircleRequest: null,
joinCircleInvite: null,
joinCircle: null,
adminSettingsCircle: null,
leaveCircle: null,
destroyCircle: null,
settingsPanel: null,
settingsName: null,
settingsDesc: null,
settingsPassword: null,
settingsSinglePasswordEnabled: null,
settingsSinglePassword: null,
settingsEntrySinglePassword: null,
settingsLimit: null,
settingsEntryLimit: null,
settingsLink: null,
settingsLinkAuto: null,
settingsLinkFiles: null,
settingsEntryLink: null,
settingsEntryLinkAuto: null,
settingsEntryLinkFiles: null,
settingsSave: null,
addMember: null,
linkGroup: null,
linkCircle: null,
buttonCircleActions: null,
buttonCircleActionReturn: null,
buttonCircleSettings: null,
buttonAddMember: null,
buttonLinkGroup: null,
buttonLinkCircle: null,
initElements: function() {
elements.newTypeDefinition = $('#circles_new_type_definition');
elements.newType = $('#circles_new_type');
elements.newSubmit = $('#circles_new_submit');
elements.newName = $('#circles_new_name');
elements.navigation = $('#circle-navigation.circles');
elements.circlesList = $('#circles_list');
elements.circlesSearch = $('#circles_search');
elements.circlesFilters = $('#circles_filters');
elements.circleDetails = $('#circle_details')
elements.circleDesc = $('#circle_desc');
elements.emptyContent = $('#emptycontent');
elements.mainUI = $('#mainui');
elements.mainUIMembers = $('#memberslist');
elements.mainUIMembersTable = $('#memberslist_table');
elements.mainUIGroupsTable = $('#groupslist_table');
elements.mainUILinksTable = $('#linkslist_table');
elements.membersSearchResult = $('#members_search_result');
elements.groupsSearchResult = $('#groups_search_result');
elements.memberDetails = $('#memberdetails');
elements.memberRequest = $('#member_request');
elements.joinCircleInteraction = $('#sjoincircle_interact');
elements.joinCircleAccept = $('#joincircle_acceptinvit');
elements.joinCircleReject = $('#joincircle_rejectinvit');
elements.joinCircleRequest = $('#joincircle_request');
elements.joinCircleInvite = $('#joincircle_invit');
elements.joinCircle = $('#joincircle');
elements.leaveCircle = $('#leavecircle');
elements.destroyCircle = $('#circle-actions-delete');
elements.adminSettingsCircle = $('#adminsettingscircle');
elements.adminSettingsCircle.hide().on('click', function() {
settings.displaySettings(true);
});
elements.settingsPanel = $('#settings-panel');
elements.settingsName = $('#settings-name');
elements.settingsDesc = $('#settings-desc');
elements.settingsEntryLimit = $('#settings-entry-limit');
elements.settingsPassword = $('#settings-password');
elements.settingsSinglePassword = $('#single-password');
elements.settingsSinglePasswordEnabled = $('#single-password-enabled');
elements.settingsEntrySinglePassword = $('#settings-password-single');
elements.settingsLimit = $('#settings-limit');
// elements.settingsLimit.prop('disabled', !OC.isUserAdmin());
elements.settingsLink = $('#settings-link');
elements.settingsLinkAuto = $('#settings-link-auto');
elements.settingsLinkFiles = $('#settings-link-files');
elements.settingsEntryLink = $('#settings-entry-link');
elements.settingsEntryLinkAuto = $('#settings-entry-link-auto');
elements.settingsEntryLinkFiles = $('#settings-entry-link-files');
elements.settingsSave = $('#settings-submit');
elements.addMember = $('#addmember');
elements.linkGroup = $('#linkgroup');
elements.linkCircle = $('#linkcircle');
elements.buttonCircleActions = $('#circle-actions-buttons');
elements.buttonCircleActionReturn = $('#circle-actions-return');
elements.buttonCircleSettings = $('#circle-actions-settings');
elements.buttonAddMember = $('#circle-actions-add');
elements.buttonLinkGroup = $('#circle-actions-group');
elements.buttonLinkCircle = $('#circle-actions-link');
elements.buttonJoinCircle = $('#circle-actions-join');
},
initTweaks: function() {
$.fn.emptyTable = function() {
this.children('tr').each(function() {
if ($(this).attr('class') !== 'header') {
$(this).remove();
}
});
};
},
initUI: function() {
elements.newTypeDefinition.children('div').fadeOut(0);
$('#circles_new_type_' + elements.newType.children('option:selected').val()).fadeIn(
0);
elements.newType.hide();
elements.newSubmit.hide();
elements.newTypeDefinition.hide();
$('.icon-circles').css('background-image',
'url(' + OC.imagePath('circles', 'colored') + ')');
$('.icon-add-user').css('background-image',
'url(' + OC.imagePath('circles', 'add-user') + ')');
$('.icon-link-group').css('background-image',
'url(' + OC.imagePath('circles', 'link-group') + ')');
$('.icon-join').css('background-image',
'url(' + OC.imagePath('circles', 'join') + ')');
var theme = $('#body-user').find('#header').css('background-color');
elements.circlesList.css('background-color', theme);
elements.circleDetails.css('background-color', theme);
elements.membersSearchResult.hide();
elements.groupsSearchResult.hide();
},
/**
*
*/
initExperienceCirclesList: function() {
elements.circlesList.children('div').on('click', function() {
nav.displayCirclesList($(this).attr('circle-type'));
});
this.initExperienceCirclesListFromSearch();
this.initExperienceCirclesListFromFilter();
},
initExperienceCirclesListFromSearch: function() {
this.circlesSearch.on('input property paste focus', function() {
var search = $(this).val().trim();
if (curr.searchCircle === search) {
return;
}
curr.searchCircle = search;
api.listCircles(curr.circlesType, curr.searchCircle, curr.searchFilter,
resultCircles.listCirclesResult);
});
},
initExperienceCirclesListFromFilter: function() {
this.circlesFilters.on('input property paste focus', function() {
var searchFilter = $(this).val();
if (curr.searchFilter === searchFilter) {
return;
}
curr.searchFilter = searchFilter;
api.listCircles(curr.circlesType, curr.searchCircle, curr.searchFilter,
resultCircles.listCirclesResult);
});
},
/**
*
*/
initExperienceCircleButtons: function() {
elements.buttonCircleActionReturn.hide();
elements.buttonCircleActionReturn.on('click', function() {
nav.circlesActionReturn();
});
elements.buttonAddMember.on('click', function() {
settings.displaySettings(false);
nav.displayCircleButtons(false);
nav.displayAddMemberInput(true);
nav.displayLinkGroupInput(false);
nav.displayLinkCircleInput(false);
nav.displayJoinCircleButton(false);
});
elements.buttonLinkGroup.on('click', function() {
settings.displaySettings(false);
nav.displayCircleButtons(false);
nav.displayAddMemberInput(false);
nav.displayLinkGroupInput(true);
nav.displayLinkCircleInput(false);
nav.displayJoinCircleButton(false);
});
elements.buttonLinkCircle.on('click', function() {
settings.displaySettings(false);
nav.displayCircleButtons(false);
nav.displayAddMemberInput(false);
nav.displayLinkGroupInput(false);
nav.displayLinkCircleInput(true);
nav.displayJoinCircleButton(false);
});
elements.buttonCircleSettings.on('click', function() {
settings.displaySettings(true);
nav.displayCircleButtons(false);
nav.displayAddMemberInput(false);
nav.displayLinkGroupInput(false);
nav.displayLinkCircleInput(false);
nav.displayJoinCircleButton(false);
});
elements.buttonJoinCircle.on('click', function() {
nav.joinCircleAction();
});
elements.settingsSave.on('click', function() {
actions.saveSettings();
});
},
/**
*
*/
initAnimationNewCircle: function() {
elements.newName.on('keyup', function() {
actions.onEventNewCircleName();
});
elements.newType.on('change', function() {
actions.onEventNewCircleType();
});
elements.newSubmit.on('click', function() {
api.createCircle(Number(elements.newType.val()), elements.newName.val(),
resultCircles.createCircleResult);
});
},
emptyCircleCreation: function() {
elements.newName.val('');
elements.newType.val('');
},
fillMembersSearch: function(source, exact, partial) {
this.fillExactMembersSearch(source, exact);
this.fillPartialMembersSearch(source, partial);
elements.membersSearchResult.children().first().css('border-top-width', '0px');
},
fillExactMembersSearch: function(source, exact) {
curr.exactMemberSearchType = '';
$.each(exact, function(index, value) {
var details = nav.escapeHtml(value.value.shareWith);
if (source === 'groups') {
if (exact.length === 1) {
curr.exactMemberSearchType = 'group';
}
details = 'group';
}
elements.membersSearchResult.append(
'<div class="members_search exact" source="' + source + '" searchresult="' +
nav.escapeHtml(value.value.shareWith) + '">' + nav.escapeHtml(value.label) + ' (' +
details + ')</div>');
});
},
fillPartialMembersSearch: function(source, partial) {
$.each(partial, function(index, value) {
var currSearch = elements.addMember.val().trim();
var line = nav.escapeHtml(value.label);
if (source === 'groups') {
if (currSearch.length > 0) {
line = line.replace(new RegExp('(' + currSearch + ')', 'gi'), '<b>$1</b>');
}
line += ' (group)';
} else {
line += ' (' + nav.escapeHtml(value.value.shareWith) + ')';
if (currSearch.length > 0) {
line = line.replace(new RegExp('(' + currSearch + ')', 'gi'), '<b>$1</b>');
}
}
elements.membersSearchResult.append(
'<div class="members_search" source="' + source + '" searchresult="' +
nav.escapeHtml(value.value.shareWith) + '">' + line + '</div>');
});
},
fillGroupsSearch: function(exact, partial) {
this.fillExactGroupsSearch(exact);
this.fillPartialGroupsSearch(partial);
elements.groupsSearchResult.children().first().css('border-top-width', '0px');
},
fillExactGroupsSearch: function(exact) {
$.each(exact, function(index, value) {
elements.groupsSearchResult.append(
'<div class="groups_search exact" searchresult="' +
nav.escapeHtml(value.value.shareWith) + '">' + nav.escapeHtml(value.label) + ' (' +
nav.escapeHtml(value.value.shareWith) + ')</div>');
});
},
fillPartialGroupsSearch: function(partial) {
$.each(partial, function(index, value) {
var currSearch = elements.addMember.val().trim();
var line = nav.escapeHtml(value.label) + ' (' + nav.escapeHtml(value.value.shareWith) + ')';
if (currSearch.length > 0) {
line = line.replace(new RegExp('(' + currSearch + ')', 'gi'), '<b>$1</b>');
}
elements.groupsSearchResult.append(
'<div class="groups_search" searchresult="' +
nav.escapeHtml(value.value.shareWith) + '">' + line + '</div>');
});
},
resetCirclesList: function() {
elements.navigation.addClass('selected');
elements.navigation.children().each(function() {
if ($(this).attr('id') !== 'circles_search' &&
$(this).attr('id') !== 'circles_filters') {
$(this).remove();
}
});
},
generateTmplCircle: function(entry) {
var tmpl = $('#tmpl_circle').html();
tmpl = tmpl.replace(/%title%/g, nav.escapeHtml(entry.name));
tmpl = tmpl.replace(/%type%/g, t('circles', nav.escapeHtml(entry.type_string)));
tmpl = tmpl.replace(/%owner%/g, nav.escapeHtml(entry.owner.cached_name));
tmpl = tmpl.replace(/%status%/g, t('circles', nav.escapeHtml(entry.user.status)));
tmpl = tmpl.replace(/%level_string%/g, t('circles', nav.escapeHtml(entry.user.level_string)));
tmpl = tmpl.replace(/%creation%/g, nav.escapeHtml(entry.creation));
return tmpl;
},
generateTmplMember: function(entry) {
var tmpl = $('#tmpl_member').html();
tmpl = tmpl.replace(/%username%/g, nav.escapeHtml(entry.user_id));
tmpl = tmpl.replace(/%instance%/g, nav.escapeHtml(entry.instance));
tmpl = tmpl.replace(/%type%/g, nav.escapeHtml(entry.user_type));
let displayName = entry.display_name;
if (entry.cached_name !== '') {
displayName = entry.cached_name;
}
if (entry.instance !== '' && entry.user_type <= 2) {
displayName += ' (' + entry.instance + ')';
}
tmpl = tmpl.replace(/%displayname%/g, nav.escapeHtml(displayName));
tmpl = tmpl.replace(/%level%/g, nav.escapeHtml(entry.level));
tmpl = tmpl.replace(/%levelString%/g, nav.escapeHtml(entry.level_string));
tmpl = tmpl.replace(/%status%/g, nav.escapeHtml(entry.status));
tmpl = tmpl.replace(/%joined%/g, nav.escapeHtml(entry.joined));
return tmpl;
},
generateTmplGroup: function(entry) {
var tmpl = $('#tmpl_group').html();
tmpl = tmpl.replace(/%groupid%/g, nav.escapeHtml(entry.user_id));
tmpl = tmpl.replace(/%level%/g, nav.escapeHtml(entry.level));
tmpl = tmpl.replace(/%levelString%/g, nav.escapeHtml(entry.level_string));
// tmpl = tmpl.replace(/%joined%/g, nav.escapeHtml(entry.joined));
return tmpl;
},
generateTmplLink: function(entry) {
var tmpl = $('#tmpl_link').html();
tmpl = tmpl.replace(/%id%/g, nav.escapeHtml(entry.unique_id));
tmpl = tmpl.replace(/%token%/g, nav.escapeHtml(entry.token));
tmpl = tmpl.replace(/%address%/g, nav.escapeHtml(entry.address));
tmpl = tmpl.replace(/%status%/g, nav.escapeHtml(entry.status));
tmpl = tmpl.replace(/%joined%/g, nav.escapeHtml(entry.creation));
return tmpl;
}
};

View file

@ -1,244 +0,0 @@
/*
* Circles - Bring cloud-users closer together.
*
* This file is licensed under the Affero General Public License version 3 or
* later. See the COPYING file.
*
* @author Maxence Lange <maxence@pontapreta.net>
* @copyright 2017
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
/** global: OC */
/** global: OCA */
/** global: Notyf */
/** global: nav */
/** global: actions */
/** global: elements */
/** global: results */
/** global: resultCircles */
/** global: resultMembers */
/** global: resultGroups */
/** global: resultLinks */
var api = OCA.Circles.api;
var curr = {
userId: '',
circlesType: '',
circle: 0,
circleName: '',
circleDesc: '',
circleDetails: {},
circleLevel: 0,
circleStatus: '',
circleMembers: {},
circleGroups: {},
circleLinks: {},
searchCircle: '',
searchFilter: 0,
searchUser: '',
exactMemberSearchType: false,
searchGroup: '',
searchUserSelected: '',
allowed_linked_groups: 0,
allowed_federated_circles: 0,
allowed_circles: 0,
searchOrder: 0,
searchOrderDisplayed: 0,
defineCircle: function (data) {
curr.circle = data.circle_id;
curr.circleDetails = data.details;
curr.circleName = data.details.name;
curr.circleDesc = data.details.description;
curr.circleLimit = data.details.settings.members_limit;
curr.circleSettings = data.details.settings;
curr.circleLevel = data.details.viewer.level;
curr.circleStatus = data.details.viewer.status;
}
};
var define = {
typePersonal: 1,
typeSecret: 2,
typeClosed: 4,
typePublic: 8,
typeUser: 1,
typeGroup: 2,
typeMail: 3,
typeContact: 4,
levelMember: 1,
levelModerator: 4,
levelAdmin: 8,
levelOwner: 9,
linkRemove: 0,
linkDown: 1,
linkSetup: 2,
linkRefused: 4,
linkRequestSent: 5,
linkRequested: 6,
linkUp: 9,
animationSpeed: 100,
animationMenuSpeed: 60,
status: {
0: t('circles', 'Link Removed'),
1: t('circles', 'Link down'),
2: t('circles', 'Setting link'),
4: t('circles', 'Request dismissed'),
5: t('circles', 'Request sent'),
6: t('circles', 'Link requested'),
9: t('circles', 'Link up')
},
linkStatus: function (status) {
return define.status[parseInt(status)];
}
};
$(document).ready(function () {
/**
* @constructs Navigation
*/
var Navigation = function () {
$.extend(Navigation.prototype, curr);
$.extend(Navigation.prototype, nav);
$.extend(Navigation.prototype, elements);
$.extend(Navigation.prototype, actions);
$.extend(Navigation.prototype, settings);
$.extend(Navigation.prototype, resultCircles);
$.extend(Navigation.prototype, resultMembers);
$.extend(Navigation.prototype, resultGroups);
$.extend(Navigation.prototype, resultLinks);
this.init();
this.initTransifex();
this.retrieveSettings();
};
Navigation.prototype = {
init: function () {
elements.initElements();
elements.initUI();
elements.initTweaks();
elements.initAnimationNewCircle();
elements.initExperienceCirclesList();
elements.initExperienceCircleButtons();
//elements.initExperienceMemberDetails();
nav.initNavigation();
},
initTransifex: function () {
t('circles', 'Personal Circle');
t('circles', 'Secret Circle');
t('circles', 'Closed Circle');
t('circles', 'Public Circle');
t('circles', 'Personal');
t('circles', 'Secret');
t('circles', 'Closed');
t('circles', 'Public');
t('circles', 'Not a member');
t('circles', 'Member');
t('circles', 'Moderator');
t('circles', 'Admin');
t('circles', 'Owner');
t('circles', 'Unknown');
t('circles', 'Invited');
t('circles', 'Requesting');
t('circles', 'Blocked');
t('circles', 'Removed');
},
retrieveSettings: function () {
var self = this;
$.ajax({
method: 'GET',
url: OC.generateUrl('/apps/circles/settings')
}).done(function (result) {
self.retrieveSettingsResult(result)
}).fail(function () {
self.retrieveSettingsResult({status: -1});
});
},
retrieveSettingsResult: function (result) {
if (result.status !== 1) {
return;
}
curr.userId = result.user_id;
curr.allowed_circles = result.allowed_circles;
curr.allowed_linked_groups = result.allowed_linked_groups;
curr.allowed_federated_circles = result.allowed_federated_circles;
var circleId = window.location.hash.substr(1);
if (circleId) {
actions.selectCircle(circleId);
}
}
};
/**
* @constructs Notification
*/
var Notification = function () {
this.initialize();
};
Notification.prototype = {
initialize: function () {
//noinspection SpellCheckingInspection
var notyf = new Notyf({
delay: 5000
});
this.onSuccess = function (text) {
notyf.confirm(text);
};
this.onFail = function (text) {
notyf.alert(text);
};
}
};
OCA.Circles.Navigation = Navigation;
OCA.Circles.navigation = new Navigation();
OCA.Notification = Notification;
OCA.notification = new Notification();
});

View file

@ -1,757 +0,0 @@
/*
* Circles - Bring cloud-users closer together.
*
* This file is licensed under the Affero General Public License version 3 or
* later. See the COPYING file.
*
* @author Maxence Lange <maxence@pontapreta.net>
* @copyright 2017
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
/** global: OC */
/** global: OCA */
/** global: Notyf */
/** global: actions */
/** global: nav */
/** global: elements */
/** global: settings */
/** global: resultCircles */
/** global: resultMembers */
/** global: resultGroups */
/** global: resultLinks */
/** global: curr */
/** global: api */
/** global: define */
var nav = {
escapeHtml: function(string) {
var str = '' + string
var matchHtmlRegExp = /["'&<>]/
var match = matchHtmlRegExp.exec(str)
if (!match) {
return str
}
var escape
var html = ''
var index = 0
var lastIndex = 0
for (index = match.index; index < str.length; index++) {
switch (str.charCodeAt(index)) {
case 34: // "
escape = '&quot;'
break
case 38: // &
escape = '&amp;'
break
case 39: // '
escape = '&#39;'
break
case 60: // <
escape = '&lt;'
break
case 62: // >
escape = '&gt;'
break
default:
continue
}
if (lastIndex !== index) {
html += str.substring(lastIndex, index)
}
lastIndex = index + 1
html += escape
}
return lastIndex !== index
? html + str.substring(lastIndex, index)
: html
},
initNavigation: function() {
this.initElementsAddMemberNavigation();
this.initElementsLinkCircleNavigation();
this.initElementsCircleNavigation();
this.displayCirclesList('all');
},
initElementsAddMemberNavigation: function() {
elements.addMember.hide();
elements.addMember.on('input propertychange paste focus', function() {
var search = $(this).val().trim();
if (search === '') {
elements.membersSearchResult.fadeOut(curr.animationMenuSpeed);
return;
}
if (!_.isUndefined(elements.searchTimeoutID)) {
clearTimeout(elements.searchTimeoutID);
}
elements.searchTimeoutID = _.delay(function() {
actions.searchMembersRequest(search);
if (elements.membersSearchResult.children().length === 0) {
elements.membersSearchResult.fadeOut(curr.animationMenuSpeed);
} else {
elements.membersSearchResult.fadeIn(curr.animationMenuSpeed);
}
}, 500);
}).blur(function() {
// Issue with some browser, let's disable it.
// setTimeout(function () {
// elements.membersSearchResult.fadeOut(curr.animationMenuSpeed);
// nav.circlesActionReturn();
// }, 100);
});
elements.addMember.on('keydown', function(e) {
if (e.keyCode === 27) {
nav.circlesActionReturn();
}
if (e.keyCode === 13) {
if (curr.exactMemberSearchType === 'group') {
OC.dialogs.confirm(
t('circles',
'This operation will add/invite all members of the group to the circle'),
t('circles', 'Please confirm'),
function(e) {
if (e === true) {
api.addMember(curr.circle, elements.addMember.val(), define.typeGroup,
'',
resultMembers.addMemberResult);
}
});
} else {
if (actions.validateEmail(elements.addMember.val())) {
api.addMember(curr.circle, elements.addMember.val(), define.typeMail, '',
resultMembers.addMemberResult);
} else {
api.addMember(curr.circle, elements.addMember.val(), define.typeUser, '',
resultMembers.addMemberResult);
}
}
}
});
elements.linkGroup.on('input propertychange paste focus', function() {
var search = $(this).val().trim();
if (search === '') {
elements.groupsSearchResult.fadeOut(curr.animationMenuSpeed);
return;
}
actions.searchGroupsRequest(search);
if (elements.groupsSearchResult.children().length === 0) {
elements.groupsSearchResult.fadeOut(curr.animationMenuSpeed);
} else {
elements.groupsSearchResult.fadeIn(curr.animationMenuSpeed);
}
}).blur(function() {
setTimeout(function() {
elements.groupsSearchResult.fadeOut(curr.animationMenuSpeed);
nav.circlesActionReturn();
}, 100);
});
elements.linkGroup.on('keydown', function(e) {
if (e.keyCode === 27) {
nav.circlesActionReturn();
}
if (e.keyCode === 13) {
api.linkGroup(curr.circle, $(this).val(), resultGroups.linkGroupResult);
}
});
},
initElementsLinkCircleNavigation: function() {
elements.linkCircle.hide();
elements.linkCircle.on('keydown', function(e) {
if (e.keyCode === 27) {
nav.circlesActionReturn();
}
if (e.keyCode !== 13) {
return;
}
api.linkCircle(curr.circle, elements.linkCircle.val().trim(),
resultLinks.linkCircleResult);
}).blur(function() {
nav.circlesActionReturn();
});
},
initElementsCircleNavigation: function() {
elements.joinCircle.hide();
elements.joinCircle.on('click', function() {
api.joinCircle(curr.circle, resultCircles.joinCircleResult);
nav.circlesActionReturn();
});
elements.leaveCircle.hide();
elements.leaveCircle.on('click', function() {
OC.dialogs.confirm(
t('circles', 'Are you sure you want to leave this circle?'),
t('circles', 'Please confirm'),
function(e) {
if (e === true) {
api.leaveCircle(curr.circle, resultCircles.leaveCircleResult);
nav.circlesActionReturn();
}
});
});
elements.destroyCircle.on('click', function() {
OC.dialogs.confirm(
t('circles', 'Are you sure you want to delete this circle?'),
t('circles', 'This action is irreversible'),
function(e) {
if (e === true) {
api.destroyCircle(curr.circle, resultCircles.destroyCircleResult);
}
});
});
elements.joinCircleAccept.on('click', function() {
api.joinCircle(curr.circle, resultCircles.joinCircleResult);
});
elements.joinCircleReject.on('click', function() {
api.leaveCircle(curr.circle, resultCircles.leaveCircleResult);
});
},
displayCirclesList: function(type) {
curr.circlesType = type;
curr.searchCircle = '';
curr.searchUser = '';
curr.circle = 0;
curr.circleLevel = 0;
elements.navigation.show('slide', 400);
elements.emptyContent.show(400);
elements.mainUI.fadeOut(400);
elements.circlesSearch.val('');
elements.addMember.val('');
elements.linkCircle.val('');
this.resetCirclesTypeSelection(type);
elements.resetCirclesList();
api.listCircles(type, '', curr.searchFilter, resultCircles.listCirclesResult);
},
resetCirclesTypeSelection: function(type) {
elements.circlesList.children('div').removeClass('selected');
elements.circlesList.children().each(function() {
if ($(this).attr('circle-type') === type.toLowerCase()) {
$(this).addClass('selected');
}
});
},
circlesActionReturn: function() {
elements.membersSearchResult.hide(0);
nav.displayCircleButtons(true);
settings.displaySettings(false);
nav.displayAddMemberInput(false);
nav.displayLinkGroupInput(false);
nav.displayLinkCircleInput(false);
nav.displayJoinCircleButton(false);
nav.displayInviteCircleButtons(false);
},
joinCircleAction: function() {
nav.displayCircleButtons(false);
nav.displayAddMemberInput(false);
nav.displayLinkCircleInput(false);
nav.displayLinkGroupInput(false);
nav.displayJoinCircleButton(true);
},
displayCircleButtons: function(display) {
if (display) {
elements.buttonCircleActionReturn.hide(define.animationMenuSpeed);
elements.buttonCircleActions.delay(define.animationMenuSpeed).show(
define.animationMenuSpeed);
} else {
elements.buttonCircleActions.hide(define.animationMenuSpeed);
elements.buttonCircleActionReturn.delay(define.animationMenuSpeed).show(
define.animationMenuSpeed);
}
},
displayAddMemberInput: function(display) {
if (display) {
elements.addMember.val('');
elements.addMember.delay(define.animationMenuSpeed).show(define.animationMenuSpeed,
function() {
$(this).focus();
});
} else {
elements.addMember.hide(define.animationMenuSpeed);
}
},
displayLinkGroupInput: function(display) {
if (display) {
elements.linkGroup.val('');
elements.linkGroup.delay(define.animationMenuSpeed).show(define.animationMenuSpeed,
function() {
$(this).focus();
});
} else {
elements.linkGroup.hide(define.animationMenuSpeed);
}
},
displayLinkCircleInput: function(display) {
if (display) {
elements.linkCircle.val('');
elements.linkCircle.delay(define.animationMenuSpeed).show(define.animationMenuSpeed,
function() {
$(this).focus();
});
} else {
elements.linkCircle.hide(define.animationMenuSpeed);
}
},
displayInviteCircleButtons: function(display) {
if (display) {
elements.joinCircleAccept.show(define.animationMenuSpeed);
elements.joinCircleReject.delay(define.animationMenuSpeed).show(
define.animationMenuSpeed);
} else {
elements.joinCircleAccept.hide(define.animationMenuSpeed);
elements.joinCircleReject.hide(define.animationMenuSpeed);
}
},
displayJoinCircleButton: function(display) {
if (display) {
if (curr.circleStatus === 'Invited') {
elements.joinCircle.hide(define.animationMenuSpeed);
elements.leaveCircle.hide(define.animationMenuSpeed);
nav.displayInviteCircleButtons(true);
} else {
nav.displayInviteCircleButtons(false);
if (curr.circleDetails.user.level === 0 && curr.circleStatus !== 'Requesting') {
elements.joinCircle.delay(define.animationMenuSpeed).show(
define.animationMenuSpeed);
elements.leaveCircle.hide(define.animationMenuSpeed);
elements.joinCircleAccept.hide(define.animationMenuSpeed);
elements.joinCircleReject.hide(define.animationMenuSpeed);
} else {
elements.leaveCircle.delay(define.animationMenuSpeed).show(
define.animationMenuSpeed);
elements.joinCircle.hide(define.animationMenuSpeed);
}
}
} else {
elements.joinCircle.hide(define.animationMenuSpeed);
elements.leaveCircle.hide(define.animationMenuSpeed);
}
},
/**
*
* @param display
*/
displayOptionsNewCircle: function(display) {
if (display) {
elements.newType.fadeIn(300);
elements.newSubmit.fadeIn(500);
elements.newTypeDefinition.fadeIn(700);
} else {
elements.newType.fadeOut(700);
elements.newSubmit.fadeOut(500);
elements.newTypeDefinition.fadeOut(300);
}
},
displayMembers: function(members) {
if (members === '') {
members = curr.circleMembers;
} else {
curr.circleMembers = members;
}
elements.mainUIMembersTable.emptyTable();
if (members === null) {
elements.mainUIMembersTable.hide(200);
return;
}
elements.mainUIMembersTable.show(200);
for (var i = 0; i < members.length; i++) {
if (members[i].user_type !== 2) {
var tmpl = elements.generateTmplMember(members[i]);
elements.mainUIMembersTable.append(tmpl);
}
}
for (i = 0; i < 10; i++) {
if (curr.circleLevel < 9 && curr.circleLevel <= i
|| curr.circleDetails.type === define.typePersonal) {
$('.level-select option[value="' + i + '"]').attr('disabled', 'disabled');
}
}
elements.mainUIMembersTable.children('tr.entry').each(function() {
var userId = $(this).attr('member-id');
var instance = $(this).attr('member-instance');
var userType = Number($(this).attr('member-type'));
if (userId === curr.userId && instance === '' && userType === define.typeUser) {
$(this).find('td.username').css('font-weight', 'bold').css('font-style', 'italic');
$(this).css('background', '#e0e0e0');
} else {
$(this).css('background', '#fff');
}
//
// level
if (curr.circleDetails.type === define.typePersonal) {
var levelString = $(this).attr('member-levelString');
$(this).find('.level').text(t('circles', levelString));
} else {
var level = Number($(this).attr('member-level'));
var levelSelect = $(this).find('.level-select');
if (level === 0) {
levelSelect.hide();
} else {
levelSelect.show(200).val(level);
}
levelSelect.on('change', function() {
actions.changeMemberLevel(userId, userType, instance, $(this).val());
});
}
//
// status
var status = $(this).attr('member-status');
var statusSelect = $(this).find('.status-select');
statusSelect.on('change', function() {
actions.changeMemberStatus(userId, userType, instance, $(this).val());
});
if (userType === define.typeUser) {
statusSelect.append($('<option>', {
value: status,
text: t('circles', status)
})).val(status);
}
if (userType === define.typeMail) {
statusSelect.append($('<option>', {
value: status,
text: t('circles', 'Mail Address')
})).val(status);
}
if (userType === define.typeContact) {
statusSelect.append($('<option>', {
value: status,
text: t('circles', 'Contact')
})).val(status);
}
if (curr.circleLevel <= $(this).attr('member-level')) {
return;
}
if (status === 'Member' || status === 'Invited') {
statusSelect.append($('<option>', {
value: 'remove_member',
text: t('circles', 'Remove from circle')
}));
}
if (status === 'Requesting') {
statusSelect.append($('<option>', {
value: 'accept_request',
text: t('circles', 'Accept the request')
}));
statusSelect.append($('<option>', {
value: 'dismiss_request',
text: t('circles', 'Dismiss the request')
}));
}
}
);
},
displayGroups: function(groups) {
if (groups === '') {
groups = curr.circleGroups;
} else {
curr.circleGroups = groups;
}
if (groups === null || groups.length === 0) {
elements.mainUIGroupsTable.hide(curr.animationSpeed);
return;
}
elements.mainUIGroupsTable.emptyTable();
elements.mainUIGroupsTable.show(200);
for (var i = 0; i < groups.length; i++) {
var tmpl = elements.generateTmplGroup(groups[i]);
elements.mainUIGroupsTable.append(tmpl);
}
for (i = 0; i < 10; i++) {
if (curr.circleLevel < 9 && curr.circleLevel <= i) {
$('.level-select option[value="' + i + '"]').attr('disabled', 'disabled');
}
if (i > define.levelMember && curr.circleDetails.type === define.typePersonal) {
$('.level-select option[value="' + i + '"]').remove();
}
}
elements.mainUIGroupsTable.children('tr.entry').each(function() {
var groupId = $(this).attr('group-id');
if (curr.circleDetails.group !== null &&
groupId === curr.circleDetails.group.user_id) {
$(this).find('td.username').css('font-weight', 'bold').css('font-style', 'italic');
$(this).css('background', '#e0e0e0');
} else {
$(this).css('background', '#fff');
}
var level = Number($(this).attr('group-level'));
var levelSelect = $(this).find('.level-select');
if (level === 0) {
levelSelect.hide();
} else {
levelSelect.show(200).val(level);
}
levelSelect.append($('<option>', {
value: 'remove_group',
text: t('circles', 'Unlink this group')
}));
levelSelect.on('change', function() {
actions.changeGroupLevel(groupId, $(this).val());
});
}
);
},
displayLinks: function(links) {
if (links === '') {
links = curr.circleLinks;
} else {
curr.circleLinks = links;
}
elements.mainUILinksTable.hide(curr.animationSpeed);
elements.mainUILinksTable.emptyTable();
if (links === null || links.length === 0) {
return;
}
elements.mainUILinksTable.show(curr.animationSpeed);
for (var i = 0; i < links.length; i++) {
var tmpl = elements.generateTmplLink(links[i]);
elements.mainUILinksTable.append(tmpl);
}
elements.mainUILinksTable.children('tr.entry').each(function() {
var linkId = $(this).attr('link-id');
var status = parseInt($(this).attr('link-status'));
var statusSelect = $(this).find('.link-status-select');
statusSelect.on('change', function() {
actions.changeLinkStatus(linkId, $(this).val());
});
statusSelect.append($('<option>', {
value: status,
text: define.linkStatus(status)
})).val(status);
if (curr.circleLevel < define.levelAdmin) {
return;
}
if (status === define.linkSetup || status === define.linkRefused ||
status === define.linkUp || status === define.linkDown) {
statusSelect.append($('<option>', {
value: define.linkRemove,
text: t('circles', 'Remove this link')
}));
}
if (status === define.linkRequestSent) {
statusSelect.append($('<option>', {
value: define.linkRemove,
text: t('circles', 'Cancel the link request')
}));
}
if (status === define.linkRequested) {
statusSelect.append($('<option>', {
value: define.linkUp,
text: t('circles', 'Accept the link request')
}));
statusSelect.append($('<option>', {
value: define.linkRemove,
text: t('circles', 'Reject the link request')
}));
}
});
},
displayCircleDetails: function(details) {
elements.circleDetails.children('#name').text(details.name);
elements.circleDesc.text(details.description);
elements.circleDetails.children('#type').text(t('circles', details.type_long_string));
if (details.description !== '') {
elements.circleDesc.html(
nav.escapeHtml(details.description).replace(/\n/g, '&nbsp;<br />')).show(
define.animationSpeed);
} else {
elements.circleDesc.text('').hide(define.animationSpeed);
}
elements.buttonCircleActions.show(300);
elements.addMember.hide(300);
},
displayMembersInteraction: function(details) {
if (details.viewer.level < define.levelModerator) {
elements.buttonAddMember.hide();
} else {
elements.buttonAddMember.show();
}
nav.displayMemberInteractionCircleLinks(details);
nav.displayMemberInteractionGroupLinks(details);
elements.joinCircleInteraction.hide();
elements.buttonJoinCircle.show();
this.displayNonMemberInteraction(details);
if (details.viewer.level !== define.levelOwner && OC.isUserAdmin()) {
elements.adminSettingsCircle.show();
} else {
elements.adminSettingsCircle.hide();
}
if (details.viewer.level === define.levelOwner) {
elements.buttonCircleSettings.show();
elements.destroyCircle.show();
elements.buttonJoinCircle.hide();
}
},
displayMemberInteractionGroupLinks: function(details) {
if (curr.allowed_linked_groups === '0' ||
details.viewer.level < define.levelAdmin
) {
elements.buttonLinkGroup.hide();
} else {
elements.buttonLinkGroup.show();
}
},
displayMemberInteractionCircleLinks: function(details) {
if (curr.allowed_federated_circles === '0' ||
curr.circleSettings['allow_links'] !== 'true' ||
details.type === define.typePersonal ||
details.viewer.level < define.levelAdmin
) {
elements.buttonLinkCircle.hide();
} else {
elements.buttonLinkCircle.show();
}
},
displayNonMemberInteraction: function(details) {
elements.joinCircleAccept.hide();
elements.joinCircleReject.hide();
elements.joinCircleRequest.hide();
elements.joinCircleInvite.hide();
elements.buttonCircleSettings.hide();
elements.destroyCircle.hide();
if (details.user.status === 'Requesting') {
elements.joinCircleRequest.show();
return;
}
if (details.user.status === 'Invited') {
elements.joinCircleInvite.show();
return;
}
if (details.viewer.level > 0) {
return;
}
setTimeout(function() {
nav.joinCircleAction();
}, 200);
}
};

View file

@ -1,170 +0,0 @@
/*
* Circles - Bring cloud-users closer together.
*
* This file is licensed under the Affero General Public License version 3 or
* later. See the COPYING file.
*
* @author Maxence Lange <maxence@pontapreta.net>
* @copyright 2017
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
/** global: OC */
/** global: OCA */
/** global: Notyf */
/** global: actions */
/** global: nav */
/** global: elements */
/** global: curr */
/** global: api */
/** global: define */
var resultCircles = {
joinCircleResult: function (result) {
if (result.status === 0) {
OCA.notification.onFail(
t('circles', "Cannot join this circle") + ': ' +
((result.error) ? result.error : t('circles', 'no error message')));
return;
}
// elements.removeMemberslistEntry(result.member.user_id, result.member.user_type);
if (result.member.level === define.levelMember) {
OCA.notification.onSuccess(
t('circles', "You have joined this circle"));
} else {
OCA.notification.onSuccess(
t('circles', "You have requested to join this circle"));
}
actions.selectCircle(result.circle_id);
},
leaveCircleResult: function (result) {
if (result.status === 1) {
elements.mainUIMembersTable.children("[member-id='" + result.user_id + "']").each(
function () {
$(this).hide(300);
});
actions.selectCircle(result.circle_id);
OCA.notification.onSuccess(
t('circles', "You have left this circle"));
return;
}
OCA.notification.onFail(
t('circles', "Cannot leave this circle") + ': ' +
((result.error) ? result.error : t('circles', 'no error message')));
},
destroyCircleResult: function (result) {
if (result.status === 1) {
actions.unselectCircle(result.circle_id);
OCA.notification.onSuccess(
t('circles', "You have deleted this circle"));
return;
}
OCA.notification.onFail(
t('circles', "Cannot delete this circle") + ': ' +
((result.error) ? result.error : t('circles', 'no error message')));
},
createCircleResult: function (result) {
var type = actions.getStringTypeFromType(result.type);
if (result.status === 1) {
OCA.notification.onSuccess(t('circles', " {type} '{name}' created", {
type: type,
name: result.name
}));
elements.emptyCircleCreation();
nav.displayCirclesList(result.circle.type_string);
actions.selectCircle(result.circle.unique_id);
return;
}
OCA.notification.onFail(
t('circles', " {type} '{name}' could not be created", {
type: type,
name: result.name
}) + ': ' +
((result.error) ? result.error : t('circles', 'no error message')));
},
selectCircleResult: function (result) {
elements.mainUIMembersTable.emptyTable();
if (result.status < 1) {
OCA.notification.onFail(
t('circles', 'Issue while retrieving the details of this circle') + ': ' +
((result.error) ? result.error : t('circles', 'no error message')));
return;
}
elements.navigation.children('.circle').removeClass('selected');
elements.navigation.children(".circle[circle-id='" + result.circle_id + "']").each(
function () {
$(this).addClass('selected');
});
elements.emptyContent.hide(400);
elements.mainUI.fadeIn(400);
curr.defineCircle(result);
nav.displayCircleDetails(result.details);
nav.displayMembersInteraction(result.details);
nav.displayMembers(result.details.members);
nav.displayGroups(result.details.groups);
nav.displayLinks(result.details.links);
},
listCirclesResult: function (result) {
if (result.status < 1) {
OCA.notification.onFail(
t('circles', 'Issue while retrieving the list of circles') + ': ' +
((result.error) ? result.error : t('circles', 'no error message')));
return;
}
elements.resetCirclesList();
var data = result.data;
for (var i = 0; i < data.length; i++) {
var tmpl = elements.generateTmplCircle(data[i]);
elements.navigation.append(
'<div class="circle" circle-id="' + data[i].unique_id + '">' + tmpl + '</div>');
}
elements.navigation.children('.circle').on('click', function () {
actions.selectCircle($(this).attr('circle-id'));
});
}
};

View file

@ -1,121 +0,0 @@
/*
* Circles - Bring cloud-users closer together.
*
* This file is licensed under the Affero General Public License version 3 or
* later. See the COPYING file.
*
* @author Maxence Lange <maxence@pontapreta.net>
* @copyright 2017
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
/** global: OC */
/** global: OCA */
/** global: Notyf */
/** global: actions */
/** global: nav */
/** global: elements */
/** global: curr */
/** global: api */
var resultGroups = {
searchGroupsResult: function (response) {
elements.groupsSearchResult.children().remove();
if (response === null) {
elements.groupsSearchResult.fadeOut(0);
return;
}
elements.fillGroupsSearch(response.ocs.data.exact.groups, response.ocs.data.groups);
if (elements.groupsSearchResult.children().length === 0) {
elements.groupsSearchResult.fadeOut(0);
return;
}
$('.groups_search').on('click', function () {
curr.searchGroupSelected = $(this).attr('searchresult');
api.linkGroup(curr.circle, curr.searchGroupSelected,
resultGroups.linkGroupResult);
});
elements.groupsSearchResult.fadeIn(300);
},
linkGroupResult: function (result) {
if (result.status === 1) {
OCA.notification.onSuccess(
t('circles', "Group '{name}' successfully added to the circle",
{name: result.name}));
nav.displayGroups(result.groups);
return;
}
OCA.notification.onFail(
t('circles', "Group '{name}' could not be added to the circle", {name: result.name}) +
': ' + ((result.error) ? result.error : t('circles', 'no error message')));
},
levelGroupResult: function (result) {
if (result.status === 1) {
OCA.notification.onSuccess(
t('circles', "Group '{name}' updated",
{name: result.name}));
nav.displayGroups(result.groups);
return;
}
nav.displayGroups('');
OCA.notification.onFail(
t('circles', "Group '{name}' could not be updated", {name: result.name}) +
': ' +
((result.error) ? result.error : t('circles', 'no error message')));
},
unlinkGroupResult: function (result) {
if (result.status === 1) {
elements.mainUIGroupsTable.children("[group-id='" + result.name + "']").each(
function () {
$(this).hide(300);
});
OCA.notification.onSuccess(
t('circles', "Group '{name}' successfully removed from the circle",
{name: result.name}));
nav.displayGroups(result.groups);
return;
}
nav.displayGroups('');
OCA.notification.onFail(
t('circles', "Group '{name}' could not be removed from the circle",
{name: result.name}) +
': ' +
((result.error) ? result.error : t('circles', 'no error message')));
}
};

View file

@ -1,87 +0,0 @@
/*
* Circles - Bring cloud-users closer together.
*
* This file is licensed under the Affero General Public License version 3 or
* later. See the COPYING file.
*
* @author Maxence Lange <maxence@pontapreta.net>
* @copyright 2017
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
/** global: OC */
/** global: OCA */
/** global: Notyf */
/** global: actions */
/** global: nav */
/** global: elements */
/** global: curr */
/** global: api */
/** global: define */
var resultLinks = {
linkCircleResult: function (result) {
if (result.status !== 1) {
OCA.notification.onFail(
t('circles', "A link to <b>{remote}</b> could not be initiated", {
remote: result.remote
}) + ': ' +
((result.error) ? result.error : t('circles', 'no error message')));
return;
}
if (result.link.status === define.linkRequestSent) {
OCA.notification.onSuccess(
t('circles', "A link to <b>{remote}</b> has been requested.", {
remote: result.remote
}));
}
if (result.link.status === define.linkUp) {
OCA.notification.onSuccess(
t('circles', "the link to <b>{remote}</b> is now up and running.", {
remote: result.remote
}));
}
curr.circleLinks = result.links;
nav.displayLinks('');
},
linkStatusResult: function (result) {
if (result.status !== 1) {
OCA.notification.onFail(
t('circles', "The status of the link could not be updated") + ': ' +
((result.error) ? result.error : t('circles', 'no error message')));
} else {
OCA.notification.onSuccess(t('circles', "The status of the link has been updated"));
curr.circleLinks = result.links;
}
nav.displayLinks('');
}
}
;

View file

@ -1,325 +0,0 @@
/*
* Circles - Bring cloud-users closer together.
*
* This file is licensed under the Affero General Public License version 3 or
* later. See the COPYING file.
*
* @author Maxence Lange <maxence@pontapreta.net>
* @copyright 2017
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
/** global: OC */
/** global: OCA */
/** global: Notyf */
/** global: actions */
/** global: nav */
/** global: elements */
/** global: curr */
/** global: api */
var resultMembers = {
generateItemResult: function(search, value) {
switch (value.type) {
case define.typeUser:
return resultMembers.generateItemUser(search, value);
case define.typeGroup:
return resultMembers.generateItemGroup(search, value);
case define.typeContact:
return resultMembers.generateItemContact(search, value);
}
},
enhanceSearchResult: function(search, display) {
display = nav.escapeHtml(display);
if (search.length > 0) {
display = display.replace(new RegExp('(' + search + ')', 'gi'), '<b>$1</b>');
}
return display;
},
generateItemUser: function(search, value) {
var instance = value.instance;
if (instance !== '') {
return '<div class="result_top">' +
resultMembers.enhanceSearchResult(search, value.data.display) + '</div>' +
'<div class="result_bot">' + t('circles', 'Global Scale User') + ' (' + instance + ')</div>';
}
return '<div class="result_top">' +
resultMembers.enhanceSearchResult(search, value.data.display) + '</div>' +
'<div class="result_bot">' + t('circles', 'Local User') + '</div>';
},
generateItemGroup: function(search, value) {
return '<div class="result_top">' +
resultMembers.enhanceSearchResult(search, value.data.display) + '</div>' +
'<div class="result_bot">' + t('circles', 'Local Group') + '</div>';
},
generateItemContact: function(search, value) {
var display = resultMembers.enhanceSearchResult(search, value.data.display);
var email = resultMembers.enhanceSearchResult(search, value.data.email);
var org = resultMembers.enhanceSearchResult(search, value.data.organization);
if (email !== '') {
email = ' - ' + email;
}
if (org !== '') {
display += ' (' + org + ')';
}
return '<div class="result_top">' + display + '</div>' +
'<div class="result_bot">' + t('circles', 'Contact') + email + '</div>';
},
searchMembersResult: function(response) {
if (response === null) {
elements.membersSearchResult.children().remove();
elements.membersSearchResult.fadeOut(0);
return;
}
if (response.order < curr.searchOrderDisplayed) {
return;
}
elements.membersSearchResult.children().remove();
curr.searchOrderDisplayed = response.order;
var currSearch = response.search;
$.each(response.result, function(index, value) {
elements.membersSearchResult.append('<div class="members_search" data-type="' +
value.type + '" data-ident="' + nav.escapeHtml(value.ident) + '" data-instance="' + nav.escapeHtml(value.instance) + '">' +
resultMembers.generateItemResult(currSearch, value) + '</div>'
)
;
});
$('.members_search').on('click', function() {
var ident = $(this).attr('data-ident');
var type = $(this).attr('data-type');
var instance = $(this).attr('data-instance');
if (instance === undefined) {
instance = '';
}
if (Number(type) === define.typeGroup) {
OC.dialogs.confirm(
t('circles',
'This operation will add/invite all members of the group to the circle'),
t('circles', 'Please confirm'),
function(e) {
if (e === true) {
api.addMember(curr.circle, ident, type, instance,
resultMembers.addMemberResult);
}
});
} else {
api.addMember(curr.circle, ident, type, instance, resultMembers.addMemberResult);
}
elements.membersSearchResult.hide(100);
});
// elements.fillMembersSearch('users', response.ocs.data.exact.users,
// response.ocs.data.users); elements.fillMembersSearch('groups',
// response.ocs.data.exact.groups, response.ocs.data.groups); if
// (elements.membersSearchResult.children().length === 0) {
// elements.membersSearchResult.fadeOut(0); return; } $('.members_search').on('click',
// function () { curr.searchUserSelected = $(this).attr('searchresult'); if
// ($(this).attr('source') === 'groups') { OC.dialogs.confirm( t('circles', 'This
// operation will add/invite all members of the group to the circle'), t('circles', 'Please
// confirm'), function (e) { if (e === true) { api.addGroupMembers(curr.circle,
// curr.searchUserSelected, resultMembers.addGroupMembersResult); } }); } else {
// api.addMember(curr.circle, curr.searchUserSelected, resultMembers.addMemberResult); } });
elements.membersSearchResult.fadeIn(300);
},
addMemberResult: function(result) {
resultMembers.addMemberUserResult(result);
resultMembers.addMemberGroupResult(result);
resultMembers.addMemberMailResult(result);
resultMembers.addMemberContactResult(result);
},
addMemberUserResult: function(result) {
if (result.user_type !== define.typeUser) {
return;
}
if (curr.circleDetails.type === define.typeClosed) {
resultMembers.inviteMemberResult(result);
return;
}
if (result.status === 1) {
OCA.notification.onSuccess(t('circles', "A new member was added to the circle"));
nav.displayMembers(result.members);
return;
}
OCA.notification.onFail(
t('circles', "Member could not be added to the circle") +
': ' + ((result.error) ? result.error : t('circles', 'no error message')));
},
addMemberMailResult: function(result) {
if (result.user_type !== define.typeMail) {
return;
}
if (result.status === 1) {
OCA.notification.onSuccess(
t('circles', "The email address '{email}' was added to the circle",
{email: result.display}));
nav.displayMembers(result.members);
return;
}
OCA.notification.onFail(
t('circles', "The email address '{email}' could not be added to the circle",
{email: result.display}) +
': ' + ((result.error) ? result.error : t('circles', 'no error message')));
},
addMemberContactResult: function(result) {
if (result.user_type !== define.typeContact) {
return;
}
if (result.status === 1) {
OCA.notification.onSuccess(t('circles', "A new contact was added to the circle"));
nav.displayMembers(result.members);
return;
}
OCA.notification.onFail(
t('circles', "Contact could not be added to the circle") +
': ' + ((result.error) ? result.error : t('circles', 'no error message')));
},
inviteMemberResult: function(result) {
if (result.status === 1) {
OCA.notification.onSuccess(
t('circles', "A new member was invited to the circle"));
nav.displayMembers(result.members);
return;
}
OCA.notification.onFail(
t('circles', "Member could not be invited to the circle") +
': ' + ((result.error) ? result.error : t('circles', 'no error message')));
},
addMemberGroupResult: function(result) {
if (result.user_type !== define.typeGroup) {
return;
}
if (curr.circleDetails.type === define.typeClosed) {
resultMembers.inviteMemberGroupResult(result);
return;
}
if (result.status === 1) {
OCA.notification.onSuccess(
t('circles', "Members of the group '{name}' were added to the circle",
{name: result.display}));
nav.displayMembers(result.members);
return;
}
OCA.notification.onFail(
t('circles', "Members of the group '{name}' could not be added to the circle",
{name: result.display}) +
': ' +
((result.error) ? result.error : t('circles', 'no error message')));
},
inviteMemberGroupResult: function(result) {
if (result.status === 1) {
OCA.notification.onSuccess(
t('circles', "Members of the group '{name}' were invited to the circle",
{name: result.display}));
nav.displayMembers(result.members);
return;
}
OCA.notification.onFail(
t('circles', "Members of the group '{name}' could not be invited to the circle",
{name: result.display}) +
': ' +
((result.error) ? result.error : t('circles', 'no error message')));
},
removeMemberResult: function(result) {
if (result.status === 1) {
elements.mainUIMembersTable.children("[member-id='" + result.user_id + "']").each(
function() {
if (Number($(this).attr('member-type')) === result.user_type) {
$(this).hide(300);
}
});
OCA.notification.onSuccess(t('circles', "Member was removed from the circle"));
return;
}
OCA.notification.onFail(
t('circles', "Member could not be removed from the circle") +
': ' + ((result.error) ? result.error : t('circles', 'no error message')));
},
levelMemberResult: function(result) {
if (result.status === 1) {
OCA.notification.onSuccess(
t('circles', "Member updated"));
nav.displayMembers(result.members);
return;
}
nav.displayMembers('');
OCA.notification.onFail(
t('circles', "Member could not be updated") + ': ' +
((result.error) ? result.error : t('circles', 'no error message')));
}
};

View file

@ -1,146 +0,0 @@
/*
* Circles - Bring cloud-users closer together.
*
* This file is licensed under the Affero General Public License version 3 or
* later. See the COPYING file.
*
* @author Maxence Lange <maxence@pontapreta.net>
* @copyright 2017
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
/** global: OC */
/** global: OCA */
/** global: Notyf */
/** global: curr */
/** global: define */
/** global: elements */
/** global: nav */
var settings = {
displaySettings: function(display) {
if (display) {
settings.initUISettings();
elements.circleDesc.hide(define.animationSpeed);
elements.mainUIMembers.hide(define.animationSpeed);
elements.settingsPanel.delay(define.animationSpeed).show(define.animationSpeed);
} else {
elements.settingsPanel.hide(define.animationSpeed);
elements.mainUIMembers.delay(define.animationSpeed).show(define.animationSpeed);
}
},
initUISettings: function() {
elements.settingsName.val(curr.circleName);
elements.settingsDesc.val(curr.circleDesc);
elements.settingsLimit.val(curr.circleLimit);
// single-password-enabled
elements.settingsPassword.prop('checked',
(curr.circleSettings['password_enforcement'] === 'true'));
elements.settingsPassword.on('change', function() {
settings.interactUISettings();
});
elements.settingsSinglePassword.val('');
elements.settingsSinglePasswordEnabled.prop('checked',
(curr.circleSettings['password_single_enabled'] === 'true'));
elements.settingsSinglePasswordEnabled.on('change', function() {
settings.interactUISettings();
});
if (OC.isUserAdmin()) {
elements.settingsEntryLimit.show();
} else {
elements.settingsEntryLimit.hide();
}
elements.settingsLink.prop('checked', (curr.circleSettings['allow_links'] === 'true'));
elements.settingsLinkAuto.prop('checked',
(curr.circleSettings['allow_links_auto'] === 'true'));
elements.settingsLinkFiles.prop('checked',
(curr.circleSettings['allow_links_files'] === 'true'));
elements.settingsLink.on('change', function() {
settings.interactUISettings();
});
settings.interactUISettings();
},
interactUISettings: function() {
if (elements.settingsPassword.is(":checked")) {
settings.enableSetting(elements.settingsEntrySinglePassword, elements.settingsSinglePassword,
true);
settings.enableSetting(null, elements.settingsSinglePasswordEnabled, true);
if (elements.settingsSinglePasswordEnabled.is(":checked")) {
settings.enableSetting(null, elements.settingsSinglePassword, true);
} else {
settings.enableSetting(null, elements.settingsSinglePassword,
false);
}
} else {
settings.enableSetting(null, elements.settingsSinglePasswordEnabled, false);
settings.enableSetting(elements.settingsEntrySinglePassword, elements.settingsSinglePassword,
false);
}
if (curr.allowed_federated_circles !== '1' ||
curr.circleDetails.type === define.typePersonal) {
settings.enableSetting(elements.settingsEntryLink, elements.settingsLink, false);
settings.enableSetting(elements.settingsEntryLinkAuto, elements.settingsLinkAuto,
false);
settings.enableSetting(elements.settingsEntryLinkFiles, elements.settingsLinkFiles,
false);
return;
}
settings.enableSetting(elements.settingsEntryLink, elements.settingsLink, true);
settings.enableSetting(elements.settingsEntryLinkAuto, elements.settingsLinkAuto,
(elements.settingsLink.is(":checked")));
settings.enableSetting(elements.settingsEntryLinkFiles, elements.settingsLinkFiles,
(elements.settingsLink.is(":checked")));
},
enableSetting: function(entry, input, enable) {
if (entry !== null) {
entry.stop().fadeTo(curr.animationSpeed, (enable) ? 1 : 0.3);
}
input.prop('disabled', !enable);
},
saveSettingsResult: function(result) {
if (result.status < 1) {
OCA.notification.onFail(
t('circles', 'Issue while saving settings') + ': ' +
((result.error) ? result.error : t('circles', 'no error message')));
return;
}
nav.circlesActionReturn();
curr.defineCircle(result);
nav.displayCircleDetails(result.details);
nav.displayMembersInteraction(result.details);
OCA.notification.onSuccess(t('circles', "Settings saved."));
}
};

View file

@ -1,100 +0,0 @@
/*
* Circles - Bring cloud-users closer together.
*
* This file is licensed under the Affero General Public License version 3 or
* later. See the COPYING file.
*
* @author Maxence Lange <maxence@pontapreta.net>
* @copyright 2017
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
/** global: OC */
/** global: OCA */
var circles = {
createCircle: function (type, name, callback) {
OCA.Circles.api.request({
method: 'PUT',
url: OC.generateUrl('/apps/circles/v1/circles'),
data: {
type: type,
name: name
}
}, callback);
},
listCircles: function (type, name, level, callback) {
OCA.Circles.api.request({
method: 'GET',
url: OC.generateUrl('/apps/circles/v1/circles'),
data: {
type: type,
name: name,
level: level
}
}, callback);
},
detailsCircle: function (circleId, callback) {
OCA.Circles.api.request({
method: 'GET',
url: OC.generateUrl('/apps/circles/v1/circles/' + circleId)
}, callback);
},
joinCircle: function (circleId, callback) {
OCA.Circles.api.request({
method: 'GET',
url: OC.generateUrl('/apps/circles/v1/circles/' + circleId + '/join'),
data: {}
}, callback);
},
settingsCircle: function (circleId, settings, callback) {
OCA.Circles.api.request({
method: 'POST',
url: OC.generateUrl('/apps/circles/v1/circles/' + circleId + '/settings'),
data: {settings: settings}
}, callback);
},
leaveCircle: function (circleId, callback) {
OCA.Circles.api.request({
method: 'GET',
url: OC.generateUrl('/apps/circles/v1/circles/' + circleId + '/leave'),
data: {}
}, callback);
},
destroyCircle: function (circleId, callback) {
OCA.Circles.api.request({
method: 'DELETE',
url: OC.generateUrl('/apps/circles/v1/circles/' + circleId),
data: {}
}, callback);
}
};

View file

@ -1,90 +0,0 @@
/*
* Circles - Bring cloud-users closer together.
*
* This file is licensed under the Affero General Public License version 3 or
* later. See the COPYING file.
*
* @author Maxence Lange <maxence@pontapreta.net>
* @copyright 2017
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
/** global: OC */
/** global: OCA */
(function () {
/**
* @constructs Circles
*/
var Circles = function () {
$.extend(Circles.prototype, circles);
$.extend(Circles.prototype, members);
$.extend(Circles.prototype, links);
this.initialize();
};
Circles.prototype = {
initialize: function () {
var self = this;
this.shareToCircle = function (circleId, source, type, item, callback) {
self.request({
method: 'PUT',
url: OC.generateUrl('/apps/circles/v1/circles/' + circleId + '/share'),
data: {
source: source,
type: type,
item: item
}
}, callback)
};
this.request = function (options, callback) {
var result = {status: -1};
$.ajax(options)
.done(function (res) { self.onCallback(callback, res); })
.fail(function () { self.onCallback(callback, result); });
};
this.onCallback = function (callback, result) {
if (callback && (typeof callback === 'function')) {
if (typeof result === 'object') {
callback(result);
} else {
callback({status: -1});
}
}
};
}
};
OCA.Circles = Circles;
OCA.Circles.api = new Circles();
})();

View file

@ -1,87 +0,0 @@
/*
* Circles - Bring cloud-users closer together.
*
* This file is licensed under the Affero General Public License version 3 or
* later. See the COPYING file.
*
* @author Maxence Lange <maxence@pontapreta.net>
* @copyright 2017
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
/** global: OC */
/** global: OCA */
var links = {
linkCircle: function (circleId, remote, callback) {
OCA.Circles.api.request({
method: 'POST',
url: OC.generateUrl('/apps/circles/v1/circles/' + circleId + '/link'),
data: {
remote: remote
}
}, callback);
},
linkStatus: function (linkId, status, callback) {
OCA.Circles.api.request({
method: 'POST',
url: OC.generateUrl('/apps/circles/v1/link/' + linkId + '/status'),
data: {
status: status
}
}, callback);
},
linkGroup: function (circleId, groupId, callback) {
OCA.Circles.api.request({
method: 'PUT',
url: OC.generateUrl('/apps/circles/v1/circles/' + circleId + '/groups'),
data: {
name: groupId
}
}, callback);
},
unlinkGroup: function (circleId, groupId, callback) {
OCA.Circles.api.request({
method: 'DELETE',
url: OC.generateUrl('/apps/circles/v1/circles/' + circleId + '/groups'),
data: {
group: groupId
}
}, callback);
},
levelGroup: function (circleId, group, level, callback) {
OCA.Circles.api.request({
method: 'POST',
url: OC.generateUrl('/apps/circles/v1/circles/' + circleId + '/group/level'),
data: {
group: group,
level: level
}
}, callback);
}
};

View file

@ -1,86 +0,0 @@
/*
* Circles - Bring cloud-users closer together.
*
* This file is licensed under the Affero General Public License version 3 or
* later. See the COPYING file.
*
* @author Maxence Lange <maxence@pontapreta.net>
* @copyright 2017
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
/** global: OC */
/** global: OCA */
/** global: curr */
var members = {
searchUsers: function(search, callback) {
curr.searchOrder++;
OCA.Circles.api.request({
method: 'GET',
url: OC.generateUrl('/apps/circles/v1/globalsearch'),
data: {
search: search,
order: curr.searchOrder
}
}, callback);
},
addMember: function(circleId, ident, type, instance, callback) {
OCA.Circles.api.request({
method: 'PUT',
url: OC.generateUrl('/apps/circles/v1/circles/' + circleId + '/member'),
data: {
ident: ident,
type: type,
instance: instance
}
}, callback);
},
removeMember: function(circleId, userId, userType, instance, callback) {
OCA.Circles.api.request({
method: 'DELETE',
url: OC.generateUrl('/apps/circles/v1/circles/' + circleId + '/member'),
data: {
member: userId,
type: Number(userType),
instance: instance
}
}, callback);
},
levelMember: function(circleId, userId, userType, instance, level, callback) {
OCA.Circles.api.request({
method: 'POST',
url: OC.generateUrl('/apps/circles/v1/circles/' + circleId + '/level'),
data: {
member: userId,
type: userType,
instance: instance,
level: level
}
}, callback);
}
};

1
js/vendor/notyf.js vendored
View file

@ -1 +0,0 @@
!function(){function n(n,t){for(property in t)t.hasOwnProperty(property)&&(n[property]=t[property]);return n}function t(n,t){var e=document.createElement("div");e.className="notyf__toast";var o=document.createElement("div");o.className="notyf__wrapper";var i=document.createElement("div");i.className="notyf__icon";var a=document.createElement("i");a.className=t;var r=document.createElement("div");r.className="notyf__message",r.innerHTML=n,i.appendChild(a),o.appendChild(i),o.appendChild(r),e.appendChild(o);var c=this;return setTimeout(function(){e.className+=" notyf--disappear",e.addEventListener(c.animationEnd,function(n){n.target==e&&c.container.removeChild(e)});var n=c.notifications.indexOf(e);c.notifications.splice(n,1)},c.options.delay),e}function e(){var n,t=document.createElement("fake"),e={transition:"animationend",OTransition:"oAnimationEnd",MozTransition:"animationend",WebkitTransition:"webkitAnimationEnd"};for(n in e)if(void 0!==t.style[n])return e[n]}this.Notyf=function(){this.notifications=[];var t={delay:2e3,alertIcon:"notyf__icon--alert",confirmIcon:"notyf__icon--confirm"};arguments[0]&&"object"==typeof arguments[0]?this.options=n(t,arguments[0]):this.options=t;var o=document.createDocumentFragment(),i=document.createElement("div");i.className="notyf",o.appendChild(i),document.body.appendChild(o),this.container=i,this.animationEnd=e()},this.Notyf.prototype.alert=function(n){var e=t.call(this,n,this.options.alertIcon);e.className+=" notyf--alert",this.container.appendChild(e),this.notifications.push(e)},this.Notyf.prototype.confirm=function(n){var e=t.call(this,n,this.options.confirmIcon);e.className+=" notyf--confirm",this.container.appendChild(e),this.notifications.push(e)}}(),function(){"function"==typeof define&&define.amd?define("Notyf",function(){return Notyf}):"undefined"!=typeof module&&module.exports?module.exports=Notyf:window.Notyf=Notyf}();

View file

@ -0,0 +1,132 @@
<?php
declare(strict_types=1);
/**
* Circles - Bring cloud-users closer together.
*
* This file is licensed under the Affero General Public License version 3 or
* later. See the COPYING file.
*
* @author Maxence Lange <maxence@artificial-owl.com>
* @copyright 2021
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
namespace OCA\Circles\Command;
use OC\Core\Command\Base;
use OCA\Circles\Model\FederatedUser;
use OCA\Circles\Model\Member;
use OCA\Circles\Service\ConfigService;
use OCA\Circles\Service\SearchService;
use Symfony\Component\Console\Helper\Table;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\ConsoleOutput;
use Symfony\Component\Console\Output\OutputInterface;
/**
* Class MembersSearch
*
* @package OCA\Circles\Command
*/
class MembersSearch extends Base {
/** @var SearchService */
private $searchService;
/** @var ConfigService */
private $configService;
/**
* MembersSearch constructor.
*
* @param SearchService $searchService
* @param ConfigService $configService
*/
public function __construct(SearchService $searchService, ConfigService $configService) {
parent::__construct();
$this->searchService = $searchService;
$this->configService = $configService;
}
protected function configure() {
parent::configure();
$this->setName('circles:members:search')
->setDescription('Change the level of a member from a Circle')
->addArgument('needle', InputArgument::REQUIRED, 'search')
->addOption('json', '', InputOption::VALUE_NONE, 'return result as JSON')
->addOption('initiator', '', InputOption::VALUE_REQUIRED, 'set an initiator to the request', '')
->addOption('status-code', '', InputOption::VALUE_NONE, 'display status code on exception');
}
/**
* @param InputInterface $input
* @param OutputInterface $output
*
* @return int
*/
protected function execute(InputInterface $input, OutputInterface $output): int {
$needle = $input->getArgument('needle');
$result = $this->searchService->search($needle);
if ($input->getOption('json')) {
$output->writeln(json_encode($result, JSON_PRETTY_PRINT));
}
$this->displaySearchResult($result);
return 0;
}
/**
* @param FederatedUser[] $result
*/
private function displaySearchResult(array $result) {
$output = new ConsoleOutput();
$output = $output->section();
$table = new Table($output);
$table->setHeaders(['SingleId', 'UserId', 'UserType', 'Instance']);
$table->render();
$local = $this->configService->getFrontalInstance();
foreach ($result as $entry) {
$table->appendRow(
[
$entry->getSingleId(),
$entry->getUserId(),
Member::$DEF_TYPE[$entry->getUserType()],
($entry->getInstance() === $local) ? '' : $entry->getInstance(),
]
);
}
}
}

View file

@ -44,6 +44,7 @@ use OCA\Circles\Service\CircleService;
use OCA\Circles\Service\ConfigService;
use OCA\Circles\Service\FederatedUserService;
use OCA\Circles\Service\MemberService;
use OCA\Circles\Service\SearchService;
use OCP\AppFramework\Http\DataResponse;
use OCP\AppFramework\OCS\OCSException;
use OCP\AppFramework\OCSController;
@ -75,6 +76,9 @@ class LocalController extends OcsController {
/** @var MemberService */
private $memberService;
/** @var SearchService */
private $searchService;
/** @var ConfigService */
protected $configService;
@ -88,18 +92,20 @@ class LocalController extends OcsController {
* @param FederatedUserService $federatedUserService
* @param CircleService $circleService
* @param MemberService $memberService
* @param SearchService $searchService
* @param ConfigService $configService
*/
public function __construct(
string $appName, IRequest $request, IUserSession $userSession,
FederatedUserService $federatedUserService, CircleService $circleService,
MemberService $memberService, ConfigService $configService
MemberService $memberService, SearchService $searchService, ConfigService $configService
) {
parent::__construct($appName, $request);
$this->userSession = $userSession;
$this->federatedUserService = $federatedUserService;
$this->circleService = $circleService;
$this->memberService = $memberService;
$this->searchService = $searchService;
$this->configService = $configService;
$this->setup('app', 'circles');
@ -127,6 +133,25 @@ class LocalController extends OcsController {
}
/**
* @NoAdminRequired
*
* @param string $needle
*
* @return DataResponse
* @throws OCSException
*/
public function search(string $needle): DataResponse {
try {
$this->setCurrentFederatedUser();
return new DataResponse($this->searchService->search($needle));
} catch (Exception $e) {
throw new OcsException($e->getMessage(), $e->getCode());
}
}
/**
* @NoAdminRequired
*

View file

@ -273,5 +273,19 @@ class MemberRequest extends MemberRequestBuilder {
return $this->getItemFromRequest($qb);
}
/**
* @param string $needle
*
* @return FederatedUser[]
*/
public function searchFederatedUsers(string $needle): array {
$qb = $this->getMemberSelectSql();
$qb->searchInDBField('user_id', '%' . $needle . '%');
$qb->groupBy('single_id');
return $this->getItemsFromRequest($qb, true);
}
}

View file

@ -34,6 +34,7 @@ namespace OCA\Circles\Db;
use daita\MySmallPhpTools\Exceptions\RowNotFoundException;
use OCA\Circles\Exceptions\MemberNotFoundException;
use OCA\Circles\Model\FederatedUser;
use OCA\Circles\Model\Member;
@ -74,13 +75,14 @@ class MemberRequestBuilder extends CoreQueryBuilder {
protected function getMemberSelectSql(): CoreRequestBuilder {
$qb = $this->getQueryBuilder();
$qb->select(
'm.circle_id', 'm.member_id', 'm.single_id', 'm.user_id', 'm.instance', 'm.user_type', 'm.level', 'm.status',
'm.circle_id', 'm.member_id', 'm.single_id', 'm.user_id', 'm.instance', 'm.user_type', 'm.level',
'm.status',
'm.note', 'm.contact_id', 'm.cached_name', 'm.cached_update', 'm.contact_meta',
'm.joined'
)
->from(self::TABLE_MEMBER, 'm')
->orderBy('m.joined')
->groupBy('m.member_id')
->groupBy('m.member_id')
->setDefaultSelectAlias('m');
return $qb;
@ -124,13 +126,19 @@ class MemberRequestBuilder extends CoreQueryBuilder {
/**
* @param CoreRequestBuilder $qb
* @param bool $asFederatedUser
*
* @return Member[]
* @return Member|FederatedUser[]
*/
public function getItemsFromRequest(CoreRequestBuilder $qb): array {
/** @var Member[] $result */
public function getItemsFromRequest(CoreRequestBuilder $qb, bool $asFederatedUser = false): array {
$object = Member::class;
if ($asFederatedUser) {
$object = FederatedUser::class;
}
/** @var Member|FederatedUser[] $result */
return $qb->asItems(
Member::class,
$object,
[
'local' => $this->configService->getFrontalInstance()
]

View file

@ -1,12 +1,16 @@
<?php
declare(strict_types=1);
/**
* Circles - Bring cloud-users closer together.
*
* This file is licensed under the Affero General Public License version 3 or
* later. See the COPYING file.
*
* @author Maxence Lange <maxence@pontapreta.net>
* @copyright 2017
* @author Maxence Lange <maxence@artificial-owl.com>
* @copyright 2021
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
@ -24,18 +28,26 @@
*
*/
namespace OCA\Circles;
use OCA\Circles\Model\SearchResult;
use OCA\Circles\Model\FederatedUser;
/**
* Interface ISearch
*
* @package OCA\Circles
*/
interface ISearch {
/**
* @param string $search
* @param string $needle
*
* @return SearchResult[]
* @return FederatedUser[]
*/
public function search($search);
public function search(string $needle): array;
}
}

View file

@ -226,7 +226,7 @@ class FederatedUser extends ManagedModel implements IFederatedUser, IDeserializa
* @return INC21QueryRow
*/
public function importFromDatabase(array $data, string $prefix = ''): INC21QueryRow {
$this->setSingleId($this->get($prefix . 'member_id', $data));
$this->setSingleId($this->get($prefix . 'single_id', $data));
$this->setUserId($this->get($prefix . 'user_id', $data));
$this->setUserType($this->getInt($prefix . 'user_type', $data));
$this->setInstance($this->get($prefix . 'instance', $data));

View file

@ -29,39 +29,42 @@ declare(strict_types=1);
*/
namespace OCA\Circles\Service;
namespace OCA\Circles\Search;
use OCP\IL10N;
use OCA\Circles\Db\MemberRequest;
use OCA\Circles\ISearch;
/**
* Class ExceptionService
* Class FederatedUsers
*
* @package OCA\Circles\Service
* @package OCA\Circles\Search
*/
class ExceptionService {
class FederatedUsers implements ISearch {
/** @var IL10N */
private $l10n;
/** @var MemberRequest */
private $memberRequest;
/**
* ExceptionService constructor.
* LocalUsers constructor.
*
* @param IL10N $l10n
* @param MemberRequest $memberRequest
*/
public function __construct(IL10N $l10n) {
$this->l10n = $l10n;
public function __construct(MemberRequest $memberRequest) {
$this->memberRequest = $memberRequest;
}
/**
* @return IL10N
* @param string $needle
*
* @return array
*/
public function getL10n(): IL10N {
return $this->l10n;
public function search(string $needle): array {
return $this->memberRequest->searchFederatedUsers($needle);
}
}

View file

@ -1,12 +1,16 @@
<?php
declare(strict_types=1);
/**
* Circles - Bring cloud-users closer together.
*
* This file is licensed under the Affero General Public License version 3 or
* later. See the COPYING file.
*
* @author Maxence Lange <maxence@pontapreta.net>
* @copyright 2017
* @author Maxence Lange <maxence@artificial-owl.com>
* @copyright 2021
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
@ -24,78 +28,54 @@
*
*/
namespace OCA\Circles\Service;
use OC;
use OCA\Circles\ISearch;
use OCP\IL10N;
use OCP\IUserManager;
use OCA\Circles\Model\FederatedUser;
use OCA\Circles\Search\FederatedUsers;
/**
* Class SearchService
*
* @package OCA\Circles\Service
*/
class SearchService {
/** @var IL10N */
private $l10n;
/** @var IUserManager */
private $userManager;
static $SERVICES = [
FederatedUsers::class
];
/** @var ConfigService */
private $configService;
/** @var MiscService */
private $miscService;
/** @var string[] */
private $searchList;
/**
* MembersService constructor.
*
* @param IL10N $l10n
* @param IUserManager $userManager
* @param ConfigService $configService
* @param MiscService $miscService
*/
public function __construct(
IL10N $l10n, IUserManager $userManager, ConfigService $configService,
MiscService $miscService
) {
$this->l10n = $l10n;
$this->userManager = $userManager;
$this->configService = $configService;
$this->miscService = $miscService;
$this->loadSearch();
public function __construct() {
}
/**
* load list of search engine
* @param string $needle
*
* @return FederatedUser[]
*/
public function loadSearch() {
$this->searchList = [
'OCA\Circles\Search\LocalUsers',
'OCA\Circles\Search\GlobalScaleUsers',
'OCA\Circles\Search\LocalGroups',
'OCA\Circles\Search\Contacts'
];
}
public function searchGlobal($str) {
public function search(string $needle): array {
$result = [];
foreach ($this->searchList as $container) {
$searcher = \OC::$server->query((string)$container);
if (!($searcher instanceof ISearch)) {
$this->miscService->log('Search ' . $container . ' is not compatible exception');
continue;
}
foreach (self::$SERVICES as $service) {
/** @var ISearch $service */
$service = OC::$server->get($service);
$result = array_merge($result, $searcher->search($str));
$result = array_merge($result, $service->search($needle));
}
return $result;
}
}