From 9febcedf936d1d806ae70eaceb3feb3349c08a26 Mon Sep 17 00:00:00 2001 From: Fabrixxm <fabrix.xm@gmail.com> Date: Tue, 17 Dec 2013 05:19:06 -0500 Subject: [PATCH] user contacts: fix #797 , add searching in url and nickname, add batch actions --- include/Contact.php | 3 +- mod/contacts.php | 151 ++++++++++++++---- view/templates/contact_template.tpl | 12 +- view/templates/contacts-template.tpl | 41 ++++- view/theme/duepuntozero/style.css | 3 + view/theme/quattro/dark/style.css | 13 ++ view/theme/quattro/green/style.css | 13 ++ view/theme/quattro/lilac/style.css | 13 ++ view/theme/quattro/quattro.less | 7 +- .../quattro/templates/contact_template.tpl | 6 +- 10 files changed, 206 insertions(+), 56 deletions(-) diff --git a/include/Contact.php b/include/Contact.php index ce1edbcc21..af77869989 100644 --- a/include/Contact.php +++ b/include/Contact.php @@ -215,13 +215,14 @@ function contact_photo_menu($contact) { $status_link = $profile_link . "?url=status"; $photos_link = $profile_link . "?url=photos"; $profile_link = $profile_link . "?url=profile"; - $contact_drop_link = $a->get_baseurl() . '/contacts/' . $contact['id'] . '/drop'; $pm_url = $a->get_baseurl() . '/message/new/' . $contact['id']; } $poke_link = $a->get_baseurl() . '/poke/?f=&c=' . $contact['id']; $contact_url = $a->get_baseurl() . '/contacts/' . $contact['id']; $posts_link = $a->get_baseurl() . '/network/0?nets=all&cid=' . $contact['id']; + $contact_drop_link = $a->get_baseurl() . "/contacts/" . $contact['id'] . '/drop?confirm=1'; + $menu = Array( 'poke' => array(t("Poke"), $poke_link), diff --git a/mod/contacts.php b/mod/contacts.php index a405cedbc6..d19c75ab96 100644 --- a/mod/contacts.php +++ b/mod/contacts.php @@ -67,11 +67,61 @@ function contacts_init(&$a) { } +function contacts_batch_actions(&$a){ + $contacts_id = $_POST['contact_batch']; + if (!is_array($contacts_id)) return; + + $orig_records = q("SELECT * FROM `contact` WHERE `id` IN (%s) AND `uid` = %d AND `self` = 0", + implode(",", $contacts_id), + intval(local_user()) + ); + + $count_actions=0; + foreach($orig_records as $orig_record) { + $contact_id = $orig_record['id']; + if (x($_POST, 'contacts_batch_update')) { + _contact_update($contact_id); + $count_actions++; + } + if (x($_POST, 'contacts_batch_block')) { + $r = _contact_block($contact_id, $orig_record); + if ($r) $count_actions++; + } + if (x($_POST, 'contacts_batch_ignore')) { + $r = _contact_ignore($contact_id, $orig_record); + if ($r) $count_actions++; + } + if (x($_POST, 'contacts_batch_archive')) { + $r = _contact_archive($contact_id, $orig_record); + if ($r) $count_actions++; + } + if (x($_POST, 'contacts_batch_drop')) { + _contact_drop($contact_id, $orig_record); + $count_actions++; + } + } + if ($count_actions>0) { + info ( sprintf( tt("%d contact edited.", "%d contacts edited", $count_actions), $count_actions) ); + } + + if(x($_SESSION,'return_url')) + goaway($a->get_baseurl(true) . '/' . $_SESSION['return_url']); + else + goaway($a->get_baseurl(true) . '/contacts'); + +} + + function contacts_post(&$a) { if(! local_user()) return; + if ($a->argv[1]==="batch") { + contacts_batch_actions($a); + return; + } + $contact_id = intval($a->argv[1]); if(! $contact_id) return; @@ -134,6 +184,49 @@ function contacts_post(&$a) { } +/*contact actions*/ +function _contact_update($contact_id) { + // pull feed and consume it, which should subscribe to the hub. + proc_run('php',"include/poller.php","$contact_id"); +} +function _contact_block($contact_id, $orig_record) { + $blocked = (($orig_record['blocked']) ? 0 : 1); + $r = q("UPDATE `contact` SET `blocked` = %d WHERE `id` = %d AND `uid` = %d LIMIT 1", + intval($blocked), + intval($contact_id), + intval(local_user()) + ); + return $r; + +} +function _contact_ignore($contact_id, $orig_record) { + $readonly = (($orig_record['readonly']) ? 0 : 1); + $r = q("UPDATE `contact` SET `readonly` = %d WHERE `id` = %d AND `uid` = %d LIMIT 1", + intval($readonly), + intval($contact_id), + intval(local_user()) + ); + return $r; +} +function _contact_archive($contact_id, $orig_record) { + $archived = (($orig_record['archive']) ? 0 : 1); + $r = q("UPDATE `contact` SET `archive` = %d WHERE `id` = %d AND `uid` = %d LIMIT 1", + intval($archived), + intval($contact_id), + intval(local_user()) + ); + if ($archived) { + q("UPDATE `item` SET `private` = 2 WHERE `contact-id` = %d AND `uid` = %d", intval($contact_id), intval(local_user())); + } + return $r; +} +function _contact_drop($contact_id, $orig_record) { + require_once('include/Contact.php'); + $a = get_app(); + + terminate_friendship($a->user,$a->contact,$orig_record); + contact_remove($orig_record['id']); +} function contacts_content(&$a) { @@ -168,57 +261,38 @@ function contacts_content(&$a) { } if($cmd === 'update') { - - // pull feed and consume it, which should subscribe to the hub. - proc_run('php',"include/poller.php","$contact_id"); + _contact_update($contact_id); goaway($a->get_baseurl(true) . '/contacts/' . $contact_id); // NOTREACHED } if($cmd === 'block') { - $blocked = (($orig_record[0]['blocked']) ? 0 : 1); - $r = q("UPDATE `contact` SET `blocked` = %d WHERE `id` = %d AND `uid` = %d LIMIT 1", - intval($blocked), - intval($contact_id), - intval(local_user()) - ); + $r = _contact_block($contact_id, $orig_record[0]); if($r) { - //notice( t('Contact has been ') . (($blocked) ? t('blocked') : t('unblocked')) . EOL ); info( (($blocked) ? t('Contact has been blocked') : t('Contact has been unblocked')) . EOL ); } + goaway($a->get_baseurl(true) . '/contacts/' . $contact_id); return; // NOTREACHED } if($cmd === 'ignore') { - $readonly = (($orig_record[0]['readonly']) ? 0 : 1); - $r = q("UPDATE `contact` SET `readonly` = %d WHERE `id` = %d AND `uid` = %d LIMIT 1", - intval($readonly), - intval($contact_id), - intval(local_user()) - ); + $r = _contact_ignore($contact_id, $orig_record[0]); if($r) { info( (($readonly) ? t('Contact has been ignored') : t('Contact has been unignored')) . EOL ); } + goaway($a->get_baseurl(true) . '/contacts/' . $contact_id); return; // NOTREACHED } if($cmd === 'archive') { - $archived = (($orig_record[0]['archive']) ? 0 : 1); - $r = q("UPDATE `contact` SET `archive` = %d WHERE `id` = %d AND `uid` = %d LIMIT 1", - intval($archived), - intval($contact_id), - intval(local_user()) - ); - if ($archived) { - q("UPDATE `item` SET `private` = 2 WHERE `contact-id` = %d AND `uid` = %d", intval($contact_id), intval(local_user())); - } + $r = _contact_archive($contact_id, $orig_record[0]); if($r) { - //notice( t('Contact has been ') . (($archived) ? t('archived') : t('unarchived')) . EOL ); info( (($archived) ? t('Contact has been archived') : t('Contact has been unarchived')) . EOL ); - } + } + goaway($a->get_baseurl(true) . '/contacts/' . $contact_id); return; // NOTREACHED } @@ -251,15 +325,13 @@ function contacts_content(&$a) { } // Now check how the user responded to the confirmation query if($_REQUEST['canceled']) { - goaway($a->get_baseurl(true) . '/' . $_SESSION['return_url']); - + if(x($_SESSION,'return_url')) + goaway($a->get_baseurl(true) . '/' . $_SESSION['return_url']); + else + goaway($a->get_baseurl(true) . '/contacts'); } - require_once('include/Contact.php'); - - terminate_friendship($a->user,$a->contact,$orig_record[0]); - - contact_remove($orig_record[0]['id']); + _contact_drop($contact_id, $orig_record[0]); info( t('Contact has been removed.') . EOL ); if(x($_SESSION,'return_url')) goaway($a->get_baseurl(true) . '/' . $_SESSION['return_url']); @@ -526,7 +598,7 @@ function contacts_content(&$a) { $search_txt = dbesc(protect_sprintf(preg_quote($search))); $searching = true; } - $sql_extra .= (($searching) ? " AND `name` REGEXP '$search_txt' " : ""); + $sql_extra .= (($searching) ? " AND (name REGEXP '$search_txt' OR url REGEXP '$search_txt' OR nick REGEXP '$search_txt') " : ""); if($nets) $sql_extra .= sprintf(" AND network = '%s' ", dbesc($nets)); @@ -604,6 +676,7 @@ function contacts_content(&$a) { $tpl = get_markup_template("contacts-template.tpl"); $o .= replace_macros($tpl, array( + '$baseurl' => $a->get_baseurl(), '$header' => t('Contacts') . (($nets) ? ' - ' . network_to_name($nets) : ''), '$tabs' => $t, '$total' => $total, @@ -613,6 +686,14 @@ function contacts_content(&$a) { '$submit' => t('Find'), '$cmd' => $a->cmd, '$contacts' => $contacts, + '$contact_drop_confirm' => t('Do you really want to delete this contact?'), + '$batch_actions' => array( + 'contacts_batch_update' => t('Update'), + 'contacts_batch_block' => t('Block')."/".t("Unblock"), + "contacts_batch_ignore" => t('Ignore')."/".t("Unignore"), + "contacts_batch_archive" => t('Archive')."/".t("Unarchive"), + "contacts_batch_drop" => t('Delete'), + ), '$paginate' => paginate($a), )); diff --git a/view/templates/contact_template.tpl b/view/templates/contact_template.tpl index 8e0e1acc7f..196254960b 100644 --- a/view/templates/contact_template.tpl +++ b/view/templates/contact_template.tpl @@ -1,8 +1,3 @@ -{{* - * AUTOMATICALLY GENERATED TEMPLATE - * DO NOT EDIT THIS FILE, CHANGES WILL BE OVERWRITTEN - * - *}} <div class="contact-entry-wrapper" id="contact-entry-wrapper-{{$contact.id}}" > <div class="contact-entry-photo-wrapper" > @@ -12,15 +7,16 @@ <a href="{{$contact.url}}" title="{{$contact.img_hover}}" /><img src="{{$contact.thumb}}" {{$contact.sparkle}} alt="{{$contact.name}}" /></a> + <input type="checkbox" class="contact-select" name="contact_batch[]" value="{{$contact.id}}"> {{if $contact.photo_menu}} <span onclick="openClose('contact-photo-menu-{{$contact.id}}');" class="fakelink contact-photo-menu-button" id="contact-photo-menu-button-{{$contact.id}}">menu</span> <div class="contact-photo-menu" id="contact-photo-menu-{{$contact.id}}"> <ul> - {{foreach $contact.photo_menu as $c}} + {{foreach $contact.photo_menu as $k=>$c}} {{if $c.2}} - <li><a target="redir" href="{{$c.1}}">{{$c.0}}</a></li> + <li><a class="{{$k}}" target="redir" href="{{$c.1}}">{{$c.0}}</a></li> {{else}} - <li><a href="{{$c.1}}">{{$c.0}}</a></li> + <li><a class="{{$k}}" href="{{$c.1}}">{{$c.0}}</a></li> {{/if}} {{/foreach}} </ul> diff --git a/view/templates/contacts-template.tpl b/view/templates/contacts-template.tpl index 66f3f5c87b..7dc6e0cec3 100644 --- a/view/templates/contacts-template.tpl +++ b/view/templates/contacts-template.tpl @@ -1,8 +1,4 @@ -{{* - * AUTOMATICALLY GENERATED TEMPLATE - * DO NOT EDIT THIS FILE, CHANGES WILL BE OVERWRITTEN - * - *}} + <h1>{{$header}}{{if $total}} ({{$total}}){{/if}}</h1> {{if $finding}}<h4>{{$finding}}</h4>{{/if}} @@ -18,11 +14,44 @@ {{$tabs}} - +<form action="{{$baseurl}}/contacts/batch/" method="POST"> {{foreach $contacts as $contact}} {{include file="contact_template.tpl"}} {{/foreach}} <div id="contact-edit-end"></div> +<div class="submit"> +{{foreach $batch_actions as $n=>$l}} + <input class="batch-action" name="{{$n}}" value="{{$l}}" type="submit"> + {{/foreach}} + </div> +</form> +<script> + $(document).ready(function() { + // javascript dialog to batch actions + $(".batch-action").click(function(e){ + if (confirm($(this).attr('value')+" ?")) { + return true; + } else { + e.preventDefault(); + return false; + } + }); + + // add javascript confirm dialog to "drop" links. Plain html url have "?confirm=1" to show confirmation form, we need to remove it + $(".drop").each(function() { + $(this).attr('href', $(this).attr('href').replace("confirm=1","") ); + $(this).click(function(e){ + if (confirm("{{$contact_drop_confirm}}")) { + return true; + } else { + e.preventDefault(); + return false; + } + }); + + }); + }); + </script> {{$paginate}} diff --git a/view/theme/duepuntozero/style.css b/view/theme/duepuntozero/style.css index 3567062a4e..77362e5524 100644 --- a/view/theme/duepuntozero/style.css +++ b/view/theme/duepuntozero/style.css @@ -1617,6 +1617,9 @@ input#dfrn-url { margin-top: 20px; } +.contact-select { position: absolute; top: 64px; left:64px; display:none; } +.contact-select:checked, +.contact-entry-photo:hover .contact-select { display:block; } .contact-photo-menu-button { position: absolute; diff --git a/view/theme/quattro/dark/style.css b/view/theme/quattro/dark/style.css index e72e557038..f09b240b34 100644 --- a/view/theme/quattro/dark/style.css +++ b/view/theme/quattro/dark/style.css @@ -1349,6 +1349,19 @@ span[id^="showmore-wrap"] { .contact-photo-wrapper { position: relative; } +.contact-select { + position: absolute; + top: 64px; + left: 64px; + display: none; +} +.contact-select:checked, +.contact-photo:hover .contact-select { + display: block; +} +.submit { + clear: both; +} .contact-photo { width: 48px; height: 48px; diff --git a/view/theme/quattro/green/style.css b/view/theme/quattro/green/style.css index 8e6a020b8a..2c664b52dc 100644 --- a/view/theme/quattro/green/style.css +++ b/view/theme/quattro/green/style.css @@ -1349,6 +1349,19 @@ span[id^="showmore-wrap"] { .contact-photo-wrapper { position: relative; } +.contact-select { + position: absolute; + top: 64px; + left: 64px; + display: none; +} +.contact-select:checked, +.contact-photo:hover .contact-select { + display: block; +} +.submit { + clear: both; +} .contact-photo { width: 48px; height: 48px; diff --git a/view/theme/quattro/lilac/style.css b/view/theme/quattro/lilac/style.css index d35ad52ed0..c75178437c 100644 --- a/view/theme/quattro/lilac/style.css +++ b/view/theme/quattro/lilac/style.css @@ -1349,6 +1349,19 @@ span[id^="showmore-wrap"] { .contact-photo-wrapper { position: relative; } +.contact-select { + position: absolute; + top: 64px; + left: 64px; + display: none; +} +.contact-select:checked, +.contact-photo:hover .contact-select { + display: block; +} +.submit { + clear: both; +} .contact-photo { width: 48px; height: 48px; diff --git a/view/theme/quattro/quattro.less b/view/theme/quattro/quattro.less index 6287a05ef8..8749267501 100644 --- a/view/theme/quattro/quattro.less +++ b/view/theme/quattro/quattro.less @@ -527,7 +527,8 @@ section { .contact-photo-wrapper { margin-left: 16px; } .contact-photo { width: 32px; height: 32px; - } + } + .contact-photo-menu-button { top: 15px !important; left: 0px !important; @@ -738,6 +739,10 @@ span[id^="showmore-wrap"] { .contact-photo-wrapper { position: relative; } +.contact-select { position: absolute; top:64px; left:64px; display:none; } +.contact-select:checked, +.contact-photo:hover .contact-select { display:block; } +.submit { clear: both; } .contact-photo { width: 48px; height: 48px; img { width: 48px; height: 48px; } diff --git a/view/theme/quattro/templates/contact_template.tpl b/view/theme/quattro/templates/contact_template.tpl index c74a513b8f..a63ffb3c9a 100644 --- a/view/theme/quattro/templates/contact_template.tpl +++ b/view/theme/quattro/templates/contact_template.tpl @@ -1,8 +1,3 @@ -{{* - * AUTOMATICALLY GENERATED TEMPLATE - * DO NOT EDIT THIS FILE, CHANGES WILL BE OVERWRITTEN - * - *}} <div class="contact-wrapper" id="contact-entry-wrapper-{{$id}}" > <div class="contact-photo-wrapper" > @@ -12,6 +7,7 @@ <a href="{{$contact.url}}" title="{{$contact.img_hover}}" /><img src="{{$contact.thumb}}" {{$contact.sparkle}} alt="{{$contact.name}}" /></a> + <input type="checkbox" class="contact-select" name="contact_batch[]" value="{{$contact.id}}"> {{if $contact.photo_menu}} <a href="#" rel="#contact-photo-menu-{{$contact.id}}" class="contact-photo-menu-button icon s16 menu" id="contact-photo-menu-button-{{$contact.id}}">menu</a> <ul class="contact-photo-menu menu-popup" id="contact-photo-menu-{{$contact.id}}">