Merge pull request #3374 from rabuzarus/20170407_-_group_edit

Frio: provide own group template + some restructuring in group.php
This commit is contained in:
Hypolite Petovan 2017-04-24 19:50:46 -04:00 committed by GitHub
commit 82ea7ead66
9 changed files with 526 additions and 102 deletions

View file

@ -1,38 +1,38 @@
<?php <?php
/**
* @file mod/group.php
* @brief The group module (create and rename contact groups, add and
* remove contacts to the contact groups
*/
function validate_members(&$item) {
$item = intval($item);
}
function group_init(App $a) { function group_init(App $a) {
if(local_user()) { if (local_user()) {
require_once('include/group.php'); require_once 'include/group.php';
$a->page['aside'] = group_side('contacts','group','extended',(($a->argc > 1) ? intval($a->argv[1]) : 0)); $a->page['aside'] = group_side('contacts', 'group', 'extended', (($a->argc > 1) ? intval($a->argv[1]) : 0));
} }
} }
function group_post(App $a) { function group_post(App $a) {
if (! local_user()) { if (! local_user()) {
notice( t('Permission denied.') . EOL); notice(t('Permission denied.') . EOL);
return; return;
} }
if(($a->argc == 2) && ($a->argv[1] === 'new')) { if (($a->argc == 2) && ($a->argv[1] === 'new')) {
check_form_security_token_redirectOnErr('/group/new', 'group_edit'); check_form_security_token_redirectOnErr('/group/new', 'group_edit');
$name = notags(trim($_POST['groupname'])); $name = notags(trim($_POST['groupname']));
$r = group_add(local_user(),$name); $r = group_add(local_user(), $name);
if ($r) { if ($r) {
info( t('Group created.') . EOL ); info(t('Group created.') . EOL);
$r = group_byname(local_user(),$name); $r = group_byname(local_user(), $name);
if ($r) { if ($r) {
goaway(App::get_baseurl() . '/group/' . $r); goaway(App::get_baseurl() . '/group/' . $r);
} }
} else { } else {
notice( t('Could not create group.') . EOL ); notice(t('Could not create group.') . EOL);
} }
goaway(App::get_baseurl() . '/group'); goaway(App::get_baseurl() . '/group');
return; // NOTREACHED return; // NOTREACHED
@ -46,7 +46,7 @@ function group_post(App $a) {
intval(local_user()) intval(local_user())
); );
if (! dbm::is_result($r)) { if (! dbm::is_result($r)) {
notice( t('Group not found.') . EOL ); notice(t('Group not found.') . EOL);
goaway(App::get_baseurl() . '/contacts'); goaway(App::get_baseurl() . '/contacts');
return; // NOTREACHED return; // NOTREACHED
} }
@ -60,7 +60,7 @@ function group_post(App $a) {
); );
if ($r) { if ($r) {
info( t('Group name changed.') . EOL ); info(t('Group name changed.') . EOL);
} }
} }
@ -73,17 +73,19 @@ function group_content(App $a) {
$change = false; $change = false;
if (! local_user()) { if (! local_user()) {
notice( t('Permission denied') . EOL); notice(t('Permission denied') . EOL);
return; return;
} }
// Switch to text mode interface if we have more than 'n' contacts or group members // Switch to text mode interface if we have more than 'n' contacts or group members
$switchtotext = get_pconfig(local_user(),'system','groupedit_image_limit'); $switchtotext = get_pconfig(local_user(), 'system', 'groupedit_image_limit');
if($switchtotext === false) if ($switchtotext === false) {
$switchtotext = get_config('system','groupedit_image_limit'); $switchtotext = get_config('system', 'groupedit_image_limit');
if($switchtotext === false) }
if ($switchtotext === false) {
$switchtotext = 400; $switchtotext = 400;
}
$tpl = get_markup_template('group_edit.tpl'); $tpl = get_markup_template('group_edit.tpl');
@ -92,7 +94,6 @@ function group_content(App $a) {
); );
if (($a->argc == 2) && ($a->argv[1] === 'new')) { if (($a->argc == 2) && ($a->argv[1] === 'new')) {
return replace_macros($tpl, $context + array( return replace_macros($tpl, $context + array(
'$title' => t('Create a group of contacts/friends.'), '$title' => t('Create a group of contacts/friends.'),
'$gname' => array('groupname', t('Group Name: '), '', ''), '$gname' => array('groupname', t('Group Name: '), '', ''),
@ -115,13 +116,13 @@ function group_content(App $a) {
$result = null; $result = null;
if (dbm::is_result($r)) { if (dbm::is_result($r)) {
$result = group_rmv(local_user(),$r[0]['name']); $result = group_rmv(local_user(), $r[0]['name']);
} }
if ($result) { if ($result) {
info( t('Group removed.') . EOL); info(t('Group removed.') . EOL);
} else { } else {
notice( t('Unable to remove group.') . EOL); notice(t('Unable to remove group.') . EOL);
} }
} }
goaway(App::get_baseurl() . '/group'); goaway(App::get_baseurl() . '/group');
@ -135,66 +136,75 @@ function group_content(App $a) {
intval($a->argv[2]), intval($a->argv[2]),
intval(local_user()) intval(local_user())
); );
if (dbm::is_result($r)) if (dbm::is_result($r)) {
$change = intval($a->argv[2]); $change = intval($a->argv[2]);
}
} }
if (($a->argc > 1) && (intval($a->argv[1]))) { if (($a->argc > 1) && (intval($a->argv[1]))) {
require_once 'include/acl_selectors.php';
require_once 'mod/contacts.php';
require_once('include/acl_selectors.php');
$r = q("SELECT * FROM `group` WHERE `id` = %d AND `uid` = %d AND `deleted` = 0 LIMIT 1", $r = q("SELECT * FROM `group` WHERE `id` = %d AND `uid` = %d AND `deleted` = 0 LIMIT 1",
intval($a->argv[1]), intval($a->argv[1]),
intval(local_user()) intval(local_user())
); );
if (! dbm::is_result($r)) { if (! dbm::is_result($r)) {
notice( t('Group not found.') . EOL ); notice(t('Group not found.') . EOL);
goaway(App::get_baseurl() . '/contacts'); goaway(App::get_baseurl() . '/contacts');
} }
$group = $r[0]; $group = $r[0];
$members = group_get_members($group['id']); $members = group_get_members($group['id']);
$preselected = array(); $preselected = array();
if(count($members)) { $entry = array();
foreach($members as $member) $id = 0;
if (count($members)) {
foreach ($members as $member) {
$preselected[] = $member['id']; $preselected[] = $member['id'];
}
} }
if($change) { if ($change) {
if(in_array($change,$preselected)) { if (in_array($change, $preselected)) {
group_rmv_member(local_user(),$group['name'],$change); group_rmv_member(local_user(), $group['name'], $change);
} } else {
else { group_add_member(local_user(), $group['name'], $change);
group_add_member(local_user(),$group['name'],$change);
} }
$members = group_get_members($group['id']); $members = group_get_members($group['id']);
$preselected = array(); $preselected = array();
if(count($members)) { if (count($members)) {
foreach($members as $member) foreach ($members as $member) {
$preselected[] = $member['id']; $preselected[] = $member['id'];
}
} }
} }
$drop_tpl = get_markup_template('group_drop.tpl'); $drop_tpl = get_markup_template('group_drop.tpl');
$drop_txt = replace_macros($drop_tpl, array( $drop_txt = replace_macros($drop_tpl, array(
'$id' => $group['id'], '$id' => $group['id'],
'$delete' => t('Delete'), '$delete' => t('Delete Group'),
'$form_security_token' => get_form_security_token("group_drop"), '$form_security_token' => get_form_security_token("group_drop"),
)); ));
$context = $context + array( $context = $context + array(
'$title' => t('Group Editor'), '$title' => t('Group Editor'),
'$gname' => array('groupname', t('Group Name: '),$group['name'], ''), '$gname' => array('groupname', t('Group Name: '), $group['name'], ''),
'$gid' => $group['id'], '$gid' => $group['id'],
'$drop' => $drop_txt, '$drop' => $drop_txt,
'$form_security_token' => get_form_security_token('group_edit'), '$form_security_token' => get_form_security_token('group_edit'),
'$edit_name' => t('Edit Group Name')
); );
} }
if(! isset($group)) if (! isset($group)) {
return; return;
}
$groupeditor = array( $groupeditor = array(
'label_members' => t('Members'), 'label_members' => t('Members'),
@ -205,14 +215,24 @@ function group_content(App $a) {
); );
$sec_token = addslashes(get_form_security_token('group_member_change')); $sec_token = addslashes(get_form_security_token('group_member_change'));
$textmode = (($switchtotext && (count($members) > $switchtotext)) ? true : false);
foreach($members as $member) { // Format the data of the group members
if($member['url']) { foreach ($members as $member) {
$member['click'] = 'groupChangeMember(' . $group['id'] . ',' . $member['id'] . ',\'' . $sec_token . '\'); return true;'; if ($member['url']) {
$groupeditor['members'][] = micropro($member,true,'mpgroup', $textmode); $entry = _contact_detail_for_template($member);
$entry['label'] = 'members';
$entry['photo_menu'] = '';
$entry['change_member'] = array(
'title' => t("Remove Contact"),
'gid' => $group['id'],
'cid' => $member['id'],
'sec_token' => $sec_token
);
$groupeditor['members'][] = $entry;
} else {
group_rmv_member(local_user(), $group['name'], $member['id']);
} }
else
group_rmv_member(local_user(),$group['name'],$member['id']);
} }
$r = q("SELECT * FROM `contact` WHERE `uid` = %d AND NOT `blocked` AND NOT `pending` AND NOT `self` ORDER BY `name` ASC", $r = q("SELECT * FROM `contact` WHERE `uid` = %d AND NOT `blocked` AND NOT `pending` AND NOT `self` ORDER BY `name` ASC",
@ -220,11 +240,20 @@ function group_content(App $a) {
); );
if (dbm::is_result($r)) { if (dbm::is_result($r)) {
$textmode = (($switchtotext && (count($r) > $switchtotext)) ? true : false); // Format the data of the contacts who aren't in the contact group
foreach($r as $member) { foreach ($r as $member) {
if(! in_array($member['id'],$preselected)) { if (! in_array($member['id'], $preselected)) {
$member['click'] = 'groupChangeMember(' . $group['id'] . ',' . $member['id'] . ',\'' . $sec_token . '\'); return true;'; $entry = _contact_detail_for_template($member);
$groupeditor['contacts'][] = micropro($member,true,'mpall', $textmode); $entry['label'] = 'contacts';
$entry['photo_menu'] = '';
$entry['change_member'] = array(
'title' => t("Add Contact"),
'gid' => $group['id'],
'cid' => $member['id'],
'sec_token' => $sec_token
);
$groupeditor['contacts'][] = $entry;
} }
} }
} }
@ -232,7 +261,11 @@ function group_content(App $a) {
$context['$groupeditor'] = $groupeditor; $context['$groupeditor'] = $groupeditor;
$context['$desc'] = t('Click on a contact to add or remove.'); $context['$desc'] = t('Click on a contact to add or remove.');
if($change) { // If there are to many contacts we could provide an alternative view mode
$total = count($groupeditor['members']) + count($groupeditor['contacts']);
$context['$shortmode'] = (($switchtotext && ($total > $switchtotext)) ? true : false);
if ($change) {
$tpl = get_markup_template('groupeditor.tpl'); $tpl = get_markup_template('groupeditor.tpl');
echo replace_macros($tpl, $context); echo replace_macros($tpl, $context);
killme(); killme();

View file

@ -5,6 +5,8 @@
id="group-delete-icon-{{$id}}" id="group-delete-icon-{{$id}}"
class="icon drophide group-delete-icon" class="icon drophide group-delete-icon"
onmouseover="imgbright(this);" onmouseover="imgbright(this);"
onmouseout="imgdull(this);" ></a> onmouseout="imgdull(this);"
title="{{$delete}}">
</a>
</div> </div>
<div class="group-delete-end"></div> <div class="group-delete-end"></div>

View file

@ -1,21 +1,62 @@
{{* Template for the contact group list *}}
{{* The contacts who are already members of the contact group *}}
<div id="group"> <div id="group">
<h3>{{$groupeditor.label_members}}</h3> <h3>{{$groupeditor.label_members}}</h3>
<div id="group-members" class="contact_list"> <div id="group-members" class="contact_list">
{{if $groupeditor.members }}
{{foreach $groupeditor.members as $c}} {{$c}} {{/foreach}} {{if $groupeditor.members }}
{{else}}
{{$groupeditor.group_is_empty}} {{foreach $groupeditor.members as $c}}
{{/if}} {{* If there are too many contacts we use another view mode *}}
</div> {{if $shortmode}}
<div id="group-members-end"></div> <div class="contact-block-textdiv mpgroup">
<hr id="group-separator" /> <a class="contact-block-link mpgroup fakelink" target="redir" onclick="groupChangeMember({{$c.change_member.gid}},{{$c.change_member.cid}},'{{$c.change_member.sec_token}}'); return true;" title="{{$c.name}} [{{$c.itemurl}}]" alt="{{$c.name}}">
{{$c.name}}"
</a>
</div>
{{else}}
{{* The normal view mode *}}
<div class="contact-block-div mpgroup">
<a class="contact-block-link mpgroup fakelink" target="redir" onclick="groupChangeMember({{$c.change_member.gid}},{{$c.change_member.cid}},'{{$c.change_member.sec_token}}'); return true;">
<img class="contact-block-img mpgroup " src="{{$c.thumb}}" title="{{$c.name}} [{{$c.itemurl}}]" alt="{{$c.name}}">
</a>
</div>
{{/if}}
{{/foreach}}
{{else}}
{{$groupeditor.group_is_empty}}
{{/if}}
</div>
<div id="group-members-end"></div>
<hr id="group-separator" />
</div> </div>
{{* The contacts who are not members of the contact group *}}
<div id="contacts"> <div id="contacts">
<h3>{{$groupeditor.label_contacts}}</h3> <h3>{{$groupeditor.label_contacts}}</h3>
<div id="group-all-contacts" class="contact_list"> <div id="group-all-contacts" class="contact_list">
{{foreach $groupeditor.contacts as $m}} {{$m}} {{/foreach}} {{foreach $groupeditor.contacts as $m}}
</div> {{* If there are too many contacts we use another view mode *}}
<div id="group-all-contacts-end"></div> {{if $shortmode}}
<div class="contact-block-textdiv mpall">
<a class="contact-block-link mpall fakelink" target="redir" onclick="groupChangeMember({{$m.change_member.gid}},{{$m.change_member.cid}},'{{$m.change_member.sec_token}}'); return true;" title="{{$m.name}} [{{$m.itemurl}}]" alt="{{$m.name}}">
{{$m.name}}
</a>
</div>
{{else}}
{{* The normal view mode *}}
<div class="contact-block-div mpall">
<a class="contact-block-link mpall fakelink" target="redir" onclick="groupChangeMember({{$m.change_member.gid}},{{$m.change_member.cid}},'{{$m.change_member.sec_token}}'); return true;">
<img class="contact-block-img mpall " src="{{$m.thumb}}" title="{{$m.name}} [{{$m.itemurl}}]" alt="{{$m.name}}">
</a>
</div>
{{/if}}
{{/foreach}}
</div>
<div id="group-all-contacts-end"></div>
</div> </div>

View file

@ -164,6 +164,9 @@ code {
padding: 8px 16px; padding: 8px 16px;
color: inherit; color: inherit;
} }
a.btn:hover {
color: #333;
}
.btn-default { .btn-default {
background: #ededed; background: #ededed;
@ -211,6 +214,12 @@ code {
padding-left: 0; padding-left: 0;
padding-right: 0; padding-right: 0;
} }
.btn-clear,
.btn-clear:active {
border: 0;
background: transparent;
box-shadow: none;
}
.btn-eventnav, btn-eventnav:hover { .btn-eventnav, btn-eventnav:hover {
font-size: 16px; font-size: 16px;
background: none; background: none;
@ -1394,6 +1403,12 @@ section #jotOpen {
border-radius: 4px; border-radius: 4px;
position: relative; position: relative;
} }
.panel.panel-inline {
margin-left: -15px;
margin-right: -15px;
margin-top: 15px;
padding: 15px;
}
.panel .panel-body { .panel .panel-body {
padding: 15px; padding: 15px;
font-size: 14px; font-size: 14px;
@ -1927,7 +1942,8 @@ ul.dropdown-menu li:hover {
font-size: 12px; font-size: 12px;
} }
.media-list > li:hover, .media-list > li:hover,
.media-list > li.selected { .media-list > li.selected,
.media-list > li.active {
border-left: 3px solid $link_color; border-left: 3px solid $link_color;
background-color: rgba(247, 247, 247, $contentbg_transp); background-color: rgba(247, 247, 247, $contentbg_transp);
} }
@ -2015,9 +2031,9 @@ ul.dropdown-menu li:hover {
.allfriends-content-wrapper, .match-content-wrapper, .dirfind-content-wrapper, .allfriends-content-wrapper, .match-content-wrapper, .dirfind-content-wrapper,
.directory-content-wrapper, .manage-content-wrapper, .notes-content-wrapper, .directory-content-wrapper, .manage-content-wrapper, .notes-content-wrapper,
.message-content-wrapper, .apps-content-wrapper, .photos-content-wrapper, .message-content-wrapper, .apps-content-wrapper, .photos-content-wrapper,
.admin-content-wrapper, .group-content-wrapper, .viewcontacts-content-wrapper, .admin-content-wrapper, .viewcontacts-content-wrapper, .dfrn_request-content-wrapper,
.dfrn_request-content-wrapper, .friendica-content-wrapper, .credits-content-wrapper, .friendica-content-wrapper, .credits-content-wrapper, .nogroup-content-wrapper,
.nogroup-content-wrapper, .profperm-content-wrapper { .profperm-content-wrapper {
min-height: calc(100vh - 150px); min-height: calc(100vh - 150px);
padding: 15px; padding: 15px;
padding-bottom: 20px; padding-bottom: 20px;
@ -2064,6 +2080,9 @@ ul.viewcontact_wrapper > li {
position: relative;*/ position: relative;*/
/*border-left: 3px solid white;*/ /*border-left: 3px solid white;*/
} }
.contact-wrapper .contact-photo-wrapper button {
padding: 0;
}
.contact-wrapper.media { .contact-wrapper.media {
overflow: visible; overflow: visible;
word-wrap: break-word; word-wrap: break-word;
@ -2094,6 +2113,9 @@ ul.viewcontact_wrapper > li {
.contact-wrapper .contact-photo-overlay-content.xl { .contact-wrapper .contact-photo-overlay-content.xl {
font-size: 48px; font-size: 48px;
} }
.contact-wrapper .contact-photo-menu {
top: auto;
}
.contact-entry-desc { .contact-entry-desc {
color: #555; color: #555;
@ -2167,6 +2189,61 @@ ul li:hover .contact-wrapper .contact-action-link:hover {
padding-top: 10px; padding-top: 10px;
} }
/* group edit page */
.group-actions {
margin-top: 20px;
margin-bottom: 10px;
font-size: 30px;
}
.group-actions button,
.group-actions a {
font-size: 18px;
}
#group-edit-wrapper {
display: none;
}
#group-update-wrapper .contact-photo-overlay {
display: none;
}
#group-update-wrapper .viewcontact_wrapper .contact-group-actions {
height: 100%;
margin-top: -10px;
display: flex;
}
#group-update-wrapper .viewcontact_wrapper .contact-action-link {
opacity: 0.8;
font-size: 20px;
line-height: 50px;
}
#group-update-wrapper .viewcontact_wrapper .contact-action-link:hover {
opacity: 1;
}
#group-update-wrapper .shortmode {
height: 53px;
overflow: hidden;
}
#group-update-wrapper .shortmode .contact-photo {
height: 32px;
width: 32px;
}
#group-update-wrapper .shortmode .media {
overflow: hidden;
}
#group-update-wrapper .shortmode .contact-entry-desc {
font-size: 12px !important;
}
#group-update-wrapper .shortmode .contact-entry-desc h4.media-heading {
margin: 0;
}
#group-update-wrapper .shortmode .contact-entry-desc h4.media-heading a {
font-size: 13px !important;
white-space: nowrap;
}
#group-update-wrapper .shortmode .contact-entry-desc .contact-entry-rel,
#group-update-wrapper .shortmode .contact-entry-desc .contact-entry-network {
display: none;
}
/* private mail */ /* private mail */
.message-content-wrapper > li { .message-content-wrapper > li {
/* we need this overwriting because we have no template file /* we need this overwriting because we have no template file

View file

@ -0,0 +1,88 @@
/**
* @file view/theme/frio/js/mod_group.js
* @brief The javascript for the group module
*/
$(document).ready(function(){
// Add an event listeners on buttons for switching the contact list view
$("body").on("click", ".group-list-switcher", function(){
switchGroupViewMode(this);
});
});
/**
* @brief Change the group membership of the contacts and fetch the new grup list
* as html
*
* @param {int} gid The group ID
* @param {int} cid The contact ID
* @param {string} sec_token The security token
*
* @returns {undefined}
*/
function groupChangeMember(gid, cid, sec_token) {
$("#contact-entry-wrapper-" + cid).fadeTo("fast", 0.33);
$(".tooltip").tooltip("hide");
$("body").css("cursor", "wait");
$.get('group/' + gid + '/' + cid + "?t=" + sec_token, function(data) {
// Insert the new group member list
$("#group-update-wrapper").html(data);
// Apply the actual gropu list view mode to the new
// group list html
var activeMode = $(".group-list-switcher.active");
switchGroupViewMode(activeMode[0]);
$("body").css("cursor", "auto");
});
}
/**
* @brief Change the group list view mode
*
* @param {object} elm The button element of the view mode switcher
* @returns {undefined}
*/
function switchGroupViewMode(elm) {
// Remove the active class from group list switcher buttons
$(".group-list-switcher").removeClass("active");
// And add it to the active button element
$(elm).addClass("active");
// Add or remove the css classes for the group list with regard to the active view mode
if (elm.id === "group-list-small") {
$("#contact-group-list > li").addClass("shortmode col-lg-6 col-md-6 col-sm-6 col-xs-12");
} else {
$("#contact-group-list > li").removeClass("shortmode col-lg-6 col-md-6 col-sm-6 col-xs-12");
}
}
/**
* @brief Filter the group member list for contacts
*
* @returns {undefined}
*/
function filterList() {
// Declare variables
var input, filter, ul, li, a, i;
input = document.getElementById("contacts-search");
filter = input.value.toUpperCase();
li = document.querySelectorAll("#contact-group-list>li");
// Loop through all list items, and hide those who don't match the search query
for (i = 0; i < li.length; i++) {
// Get the heading element
var mh = li[i].getElementsByClassName("media-heading")[0];
// The first child of the heading element should contain
// the text which we want to filter
a = mh.firstChild;
if (a.innerHTML.toUpperCase().indexOf(filter) > -1) {
li[i].style.display = "";
} else {
li[i].style.display = "none";
}
}
}

View file

@ -1,11 +1,11 @@
<div class="contact-wrapper media" id="contact-entry-wrapper-{{$contact.id}}" > <div class="contact-wrapper media" id="contact-entry-wrapper-{{$contact.id}}">
{{* This is a wrapper for the contact picture and the dropdown menu with contact relating actions *}} {{* This is a wrapper for the contact picture and the dropdown menu with contact relating actions *}}
<div class="contact-photo-wrapper dropdown pull-left" > <div class="contact-photo-wrapper dropdown media-left">
<div class="contact-entry-photo mframe" id="contact-entry-photo-{{$contact.id}}" > <div class="contact-entry-photo mframe" id="contact-entry-photo-{{$contact.id}}">
<button type="button" class="btn btn-link dropdown-toggle" id="contact-photo-menu-{{$contact.id}}" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" > <button type="button" class="btn btn-link dropdown-toggle" id="contact-photo-menu-{{$contact.id}}" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<div class="contact-photo-image-wrapper hidden-xs"> <div class="contact-photo-image-wrapper hidden-xs">
<img class="contact-photo media-object xl" src="{{$contact.thumb}}" {{$contact.sparkle}} alt="{{$contact.name}}" /> <img class="contact-photo media-object xl" src="{{$contact.thumb}}" {{$contact.sparkle}} alt="{{$contact.name}}" />
@ -45,31 +45,74 @@
</div> </div>
<div class="media-body"> <div class="media-body">
{{if $contact.photo_menu}}
{{* The contact actions like private mail, delete contact, edit contact and so on *}} {{* The contact actions like private mail, delete contact, edit contact and so on *}}
<div class="contact-actions pull-right nav-pills preferences hidden-xs"> <div class="contact-actions pull-right nav-pills preferences hidden-xs">
{{if $contact.photo_menu.pm }}<button type="button" class="contact-action-link btn-link" onclick="addToModal('{{$contact.photo_menu.pm.1}}')" data-toggle="tooltip" title="{{$contact.photo_menu.pm.0}}"><i class="fa fa-envelope" aria-hidden="true"></i></button>{{/if}} {{if $contact.photo_menu.pm}}
{{if $contact.photo_menu.poke }}<button type="button" class="contact-action-link btn-link" onclick="addToModal('{{$contact.photo_menu.poke.1}}')" data-toggle="tooltip" title="{{$contact.photo_menu.poke.0}}"><i class="fa fa-heartbeat" aria-hidden="true"></i></button>{{/if}} <button type="button" class="contact-action-link btn-link" onclick="addToModal('{{$contact.photo_menu.pm.1}}'); retrurn false;" data-toggle="tooltip" title="{{$contact.photo_menu.pm.0}}">
{{if $contact.photo_menu.network}}<a class="contact-action-link btn-link" href="{{$contact.photo_menu.network.1}}" data-toggle="tooltip" title="{{$contact.photo_menu.network.0}}"><i class="fa fa-cloud" aria-hidden="true"></i></a>{{/if}} <i class="fa fa-envelope" aria-hidden="true"></i>
{{if $contact.photo_menu.edit }}<a class="contact-action-link btn-link" href="{{$contact.photo_menu.edit.1}}" data-toggle="tooltip" title="{{$contact.photo_menu.edit.0}}"><i class="fa fa-user" aria-hidden="true"></i></a>{{/if}} </button>
{{if $contact.photo_menu.drop }}<button type="button" class="contact-action-link btn-link" onclick="addToModal('{{$contact.photo_menu.drop.1}}')" data-toggle="tooltip" title="{{$contact.photo_menu.drop.0}}"><i class="fa fa-user-times" aria-hidden="true"></i></button>{{/if}} {{/if}}
{{if $contact.photo_menu.follow }}<a class="contact-action-link btn-link" href="{{$contact.photo_menu.follow.1}}" data-toggle="tooltip" title="{{$contact.photo_menu.follow.0}}"><i class="fa fa-user-plus" aria-hidden="true"></i></a>{{/if}} {{if $contact.photo_menu.poke}}
{{if $contact.photo_menu.hide }}<a class="contact-action-link btn-link" href="{{$contact.photo_menu.hide.1}}" data-toggle="tooltip" title="{{$contact.photo_menu.hide.0}}"><i class="fa fa-times" aria-hidden="true"></i></a>{{/if}} <button type="button" class="contact-action-link btn-link" onclick="addToModal('{{$contact.photo_menu.poke.1}}'); retrurn false;" data-toggle="tooltip" title="{{$contact.photo_menu.poke.0}}">
<i class="fa fa-heartbeat" aria-hidden="true"></i>
</button>
{{/if}}
{{if $contact.photo_menu.network}}
<a class="contact-action-link btn-link" href="{{$contact.photo_menu.network.1}}" data-toggle="tooltip" title="{{$contact.photo_menu.network.0}}">
<i class="fa fa-cloud" aria-hidden="true"></i>
</a>
{{/if}}
{{if $contact.photo_menu.edit}}
<a class="contact-action-link btn-link" href="{{$contact.photo_menu.edit.1}}" data-toggle="tooltip" title="{{$contact.photo_menu.edit.0}}">
<i class="fa fa-user" aria-hidden="true"></i>
</a>
{{/if}}
{{if $contact.photo_menu.drop}}
<button type="button" class="contact-action-link btn-link" onclick="addToModal('{{$contact.photo_menu.drop.1}}'); retrurn false;" data-toggle="tooltip" title="{{$contact.photo_menu.drop.0}}">
<i class="fa fa-user-times" aria-hidden="true"></i>
</button>
{{/if}}
{{if $contact.photo_menu.follow}}
<a class="contact-action-link btn-link" href="{{$contact.photo_menu.follow.1}}" data-toggle="tooltip" title="{{$contact.photo_menu.follow.0}}">
<i class="fa fa-user-plus" aria-hidden="true"></i>
</a>
{{/if}}
{{if $contact.photo_menu.hide}}
<a class="contact-action-link btn-link" href="{{$contact.photo_menu.hide.1}}" data-toggle="tooltip" title="{{$contact.photo_menu.hide.0}}">
<i class="fa fa-times" aria-hidden="true"></i>
</a>
{{/if}}
</div> </div>
{{/if}}
{{* The button to add or remove contacts from a contact group - group edit page *}}
{{if $contact.change_member}}
<div class="contact-group-actions pull-right nav-pills preferences">
<button type="button" class="contact-action-link btn-link" onclick="groupChangeMember({{$contact.change_member.gid}},{{$contact.change_member.cid}},'{{$contact.change_member.sec_token}}'); return true;" data-toggle="tooltip" title="{{$contact.change_member.title}}">
{{if $contact.label == "members"}}
<i class="fa fa-times-circle" aria-hidden="true"></i>
{{elseif $contact.label == "contacts"}}
<i class="fa fa-plus-circle" aria-hidden="true"></i>
{{/if}}
</button>
</div>
{{/if}}
{{* The contact description (e.g. Name, Network, kind of connection and so on *}} {{* The contact description (e.g. Name, Network, kind of connection and so on *}}
<div class="contact-entry-desc"> <div class="contact-entry-desc">
<div class="contact-entry-name" id="contact-entry-name-{{$contact.id}}" > <div class="contact-entry-name" id="contact-entry-name-{{$contact.id}}">
<h4 class="media-heading"><a href="{{$contact.url}}">{{$contact.name}}</a> <h4 class="media-heading"><a href="{{$contact.url}}">{{$contact.name}}</a>
{{if $contact.account_type}} <small class="contact-entry-details" id="contact-entry-accounttype-{{$contact.id}}">({{$contact.account_type}})</small>{{/if}} {{if $contact.account_type}} <small class="contact-entry-details" id="contact-entry-accounttype-{{$contact.id}}">({{$contact.account_type}})</small>{{/if}}
{{if $contact.account_type == 'Forum'}}<i class="fa fa-comments-o" aria-hidden="true"></i>{{/if}} {{if $contact.account_type == 'Forum'}}<i class="fa fa-comments-o" aria-hidden="true"></i>{{/if}}
{{* @todo this needs some changing in core because $contact.account_type contains a translated string which may notbe the same in every language *}} {{* @todo this needs some changing in core because $contact.account_type contains a translated string which may notbe the same in every language *}}
</h4> </h4>
</div> </div>
{{if $contact.alt_text}}<div class="contact-entry-details" id="contact-entry-rel-{{$contact.id}}" >{{$contact.alt_text}}</div>{{/if}} {{if $contact.alt_text}}<div class="contact-entry-details contact-entry-rel" id="contact-entry-rel-{{$contact.id}}" >{{$contact.alt_text}}</div>{{/if}}
{{if $contact.itemurl}}<div class="contact-entry-details" id="contact-entry-url-{{$contact.id}}" >{{$contact.itemurl}}</div>{{/if}} {{if $contact.itemurl}}<div class="contact-entry-details contact-entry-url" id="contact-entry-url-{{$contact.id}}" >{{$contact.itemurl}}</div>{{/if}}
{{if $contact.tags}}<div class="contact-entry-details" id="contact-entry-tags-{{$contact.id}}" >{{$contact.tags}}</div>{{/if}} {{if $contact.tags}}<div class="contact-entry-details" id="contact-entry-tags-{{$contact.id}}" >{{$contact.tags}}</div>{{/if}}
{{if $contact.details}}<div class="contact-entry-details" id="contact-entry-details-{{$contact.id}}" >{{$contact.details}}</div>{{/if}} {{if $contact.details}}<div class="contact-entry-details contact-entry-tags" id="contact-entry-details-{{$contact.id}}" >{{$contact.details}}</div>{{/if}}
{{if $contact.network}}<div class="contact-entry-details" id="contact-entry-network-{{$contact.id}}" >{{$contact.network}}</div>{{/if}} {{if $contact.network}}<div class="contact-entry-details contact-entry-network" id="contact-entry-network-{{$contact.id}}" >{{$contact.network}}</div>{{/if}}
</div> </div>
{{* The checkbox to perform batch actions to these contacts (for batch actions have a look at contacts-template.tpl) *}} {{* The checkbox to perform batch actions to these contacts (for batch actions have a look at contacts-template.tpl) *}}
@ -88,13 +131,13 @@
{{* the following part is a nearly a copy of the part above but it is modified for working with js. {{* the following part is a nearly a copy of the part above but it is modified for working with js.
We use this part to filter the contacts with jquery.textcomplete *}} We use this part to filter the contacts with jquery.textcomplete *}}
<div class="javascript-template" rel="contact-template" style="display: none"> <div class="javascript-template" rel="contact-template" style="display: none">
<div class="contact-wrapper media" id="contact-entry-wrapper-{$id}" > <div class="contact-wrapper media" id="contact-entry-wrapper-{$id}">
{{* This is a wrapper for the contact picture and the dropdown menu with contact relating actions *}} {{* This is a wrapper for the contact picture and the dropdown menu with contact relating actions *}}
<div class="contact-photo-wrapper dropdown pull-left" > <div class="contact-photo-wrapper dropdown media-left">
<div class="contact-entry-photo mframe" id="contact-entry-photo-{$id}" > <div class="contact-entry-photo mframe" id="contact-entry-photo-{$id}">
<button type="button" class="btn btn-link dropdown-toggle" id="contact-photo-menu-{$id}" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" > <button type="button" class="btn btn-link dropdown-toggle" id="contact-photo-menu-{$id}" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<div class="contact-photo-image-wrapper hidden-xs"> <div class="contact-photo-image-wrapper hidden-xs">
<img class="contact-photo media-object xl" src="{$thumb}" {11} alt="{$name}" /> <img class="contact-photo media-object xl" src="{$thumb}" {11} alt="{$name}" />
@ -135,19 +178,58 @@ We use this part to filter the contacts with jquery.textcomplete *}}
</div> </div>
<div class="media-body"> <div class="media-body">
{if $photo_menu}
{{* The contact actions like private mail, delete contact, edit contact and so on *}} {{* The contact actions like private mail, delete contact, edit contact and so on *}}
<div class="contact-actions pull-right nav-pills preferences hidden-xs"> <div class="contact-actions pull-right nav-pills preferences hidden-xs">
{if $photo_menu.pm}<button type="button" class="contact-action-link btn-link" onclick="addToModal('{$photo_menu.pm.1}')" data-toggle="tooltip" title="{$photo_menu.pm.0}"><i class="fa fa-envelope" aria-hidden="true"></i></button>{/if} {if $photo_menu.pm}
{if $photo_menu.poke}<button type="button" class="contact-action-link btn-link" onclick="addToModal('{$photo_menu.poke.1}')" data-toggle="tooltip" title="{$photo_menu.poke.0}"><i class="fa fa-heartbeat" aria-hidden="true"></i></button>{/if} <button type="button" class="contact-action-link btn-link" onclick="addToModal('{$photo_menu.pm.1}')" data-toggle="tooltip" title="{$photo_menu.pm.0}">
{if $photo_menu.network}<a class="contact-action-link btn-link" href="{$photo_menu.network.1}" data-toggle="tooltip" title="{$photo_menu.network.0}"><i class="fa fa-cloud" aria-hidden="true"></i></a>{/if} <i class="fa fa-envelope" aria-hidden="true"></i>
{if $photo_menu.edit}<a class="contact-action-link btn-link" href="{$photo_menu.edit.1}" data-toggle="tooltip" title="{$photo_menu.edit.0}"><i class="fa fa-pencil" aria-hidden="true"></i></a>{/if} </button>
{if $photo_menu.drop}<a class="contact-action-link btn-link" href="{$photo_menu.drop.1}" data-toggle="tooltip" title="{$photo_menu.drop.0}"><i class="fa fa-user-times" aria-hidden="true"></i></a>{/if} {/if}
{if $photo_menu.follow}<a class="contact-action-link btn-link" href="{$photo_menu.follow.1}" data-toggle="tooltip" title="{$photo_menu.follow.0}"><i class="fa fa-user-plus" aria-hidden="true"></i></a>{/if} {if $photo_menu.poke}
<button type="button" class="contact-action-link btn-link" onclick="addToModal('{$photo_menu.poke.1}')" data-toggle="tooltip" title="{$photo_menu.poke.0}">
<i class="fa fa-heartbeat" aria-hidden="true"></i>
</button>
{/if}
{if $photo_menu.network}
<a class="contact-action-link btn-link" href="{$photo_menu.network.1}" data-toggle="tooltip" title="{$photo_menu.network.0}">
<i class="fa fa-cloud" aria-hidden="true"></i>
</a>
{/if}
{if $photo_menu.edit}
<a class="contact-action-link btn-link" href="{$photo_menu.edit.1}" data-toggle="tooltip" title="{$photo_menu.edit.0}">
<i class="fa fa-pencil" aria-hidden="true"></i>
</a>
{/if}
{if $photo_menu.drop}
<a class="contact-action-link btn-link" href="{$photo_menu.drop.1}" data-toggle="tooltip" title="{$photo_menu.drop.0}">
<i class="fa fa-user-times" aria-hidden="true"></i>
</a>
{/if}
{if $photo_menu.follow}
<a class="contact-action-link btn-link" href="{$photo_menu.follow.1}" data-toggle="tooltip" title="{$photo_menu.follow.0}">
<i class="fa fa-user-plus" aria-hidden="true"></i>
</a>
{/if}
</div> </div>
{/if}
{{* The button to add or remove contacts from a contact group - group edit page *}}
{if $contact.change_member}
<div class="contact-group-actions pull-right nav-pills preferences">
<button type="button" class="contact-action-link btn-link" onclick="groupChangeMember({$contact.change_member.gid},{$contact.change_member.cid},'{$contact.change_member.sec_token}'); return true;" data-toggle="tooltip" title="{$contact.change_member.title}">
{if $contact.label == "members"}
<i class="fa fa-times-circle" aria-hidden="true"></i>
{elseif $contact.label == "contacts"}
<i class="fa fa-plus-circle" aria-hidden="true"></i>
{/if}
</button>
</div>
{/if}
{{* The contact description (e.g. Name, Network, kind of connection and so on *}} {{* The contact description (e.g. Name, Network, kind of connection and so on *}}
<div class="contact-entry-desc"> <div class="contact-entry-desc">
<div class="contact-entry-name" id="contact-entry-name-{$id}" > <div class="contact-entry-name" id="contact-entry-name-{$id}">
<h4 class="media-heading"><a href="{$url}">{$name}</a> <h4 class="media-heading"><a href="{$url}">{$name}</a>
{if $account_type} <small class="contact-entry-details" id="contact-entry-accounttype-{$id}">({$account_type})</small>{/if} {if $account_type} <small class="contact-entry-details" id="contact-entry-accounttype-{$id}">({$account_type})</small>{/if}
{if $account_type == 'Forum'}<i class="fa fa-comments-o" aria-hidden="true"></i>{/if} {if $account_type == 'Forum'}<i class="fa fa-comments-o" aria-hidden="true"></i>{/if}

View file

@ -0,0 +1,5 @@
{{* Link for deleting contact groups *}}
<a href="group/drop/{{$id}}?t={{$form_security_token}}" onclick="return confirmDelete();" id="group-delete-icon-{{$id}}" class="btn btn-clear" title="{{$delete}}" data-toggle="tooltip">
<i class="fa fa-trash" aria-hidden="true"></i>
</a>

View file

@ -0,0 +1,77 @@
{{* This template is for the "group" module. It provides the user the possibility to
modify a specific contact group (remove contact group, edit contact group name,
add or remove contacts to the contact group.
*}}
<script type="text/javascript" src="view/theme/frio/js/mod_group.js"></script>
<div class="generic-page-wrapper">
{{* The buttons for editing the contact group (edit name / remove contact group) *}}
<div class="group-actions pull-right">
<button type="button" id="group-rename" class="btn btn-clear" onclick="openClose('group-edit-wrapper'); return false;" title="{{$edit_name}}" data-toggle="tooltip">
<i class="fa fa-pencil" aria-hidden="true"></i>
</button>
{{if $drop}}{{$drop}}{{/if}}
</div>
{{include file="section_title.tpl"}}
{{* Edit the name of the group *}}
<div id="group-edit-wrapper" class="panel panel-inline">
<form action="group/{{$gid}}" id="group-edit-form" method="post">
<input type='hidden' name='form_security_token' value='{{$form_security_token}}'>
{{include file="field_input.tpl" field=$gname}}
<div id="group-edit-submit-wrapper" class="form-group pull-right">
<button class="btn btn-primary btn-small" type="submit" name="submit" value="{{$submit|escape:'html'}}">
{{$submit|escape:'html'}}
</button>
</div>
<div id="group-edit-select-end" class="clear"></div>
</form>
</div>
{{* The search input field to search for contacts *}}
<div id="contacts-search-wrapper">
<div id="contacts-search-form" class="navbar-form" role="search">
<div class="row">
<div class="col-md-2"></div>
<div class="col-md-8 ">
<div class="form-group form-group-search">
<input type="text"
name="filter"
id="contacts-search"
class="search-input form-control form-search"
onkeyup="filterList(); return false;"
onfocus="this.select(); return false;"
/>
</div>
</div>
<div class="col-md-2"></div>
</div>
</div>
</div>
<hr>
<div id="contacts-search-end"></div>
{{if $groupeditor}}
{{* The buttons to switch between the different view modes *}}
<div id="group-list-view-switcher" class="btn-group btn-group-sm pull-right">
<botton type="button" id="group-list-big" class="active group-list-switcher btn btn-default">
<i class="fa fa-align-justify" aria-hidden="true"></i>
</botton>
<button type="button" id="group-list-small" class="btn btn-default group-list-switcher">
<i class="fa fa-th-large" aria-hidden="true"></i>
</button>
</div>
<div class="clear"></div>
{{* The contact group list *}}
<div id="group-update-wrapper">
{{include file="groupeditor.tpl"}}
</div>
{{/if}}
</div>

View file

@ -0,0 +1,19 @@
{{* Template for the contact group list *}}
<div id="group" class="contact_list">
<ul id="contact-group-list" class="viewcontact_wrapper media-list">
{{* The contacts who are already members of the contact group *}}
{{foreach $groupeditor.members as $contact}}
<li class="members active">{{include file="contact_template.tpl"}}</li>
{{/foreach}}
{{* The contacts who are not members of the contact group *}}
{{foreach $groupeditor.contacts as $contact}}
<li class="contacts">{{include file="contact_template.tpl"}}</li>
{{/foreach}}
</ul>
<div class="clear"></div>
</div>