From 7f485d1b2058a1af2f82555939df3d6c306047a3 Mon Sep 17 00:00:00 2001 From: Stephan Bergemann Date: Sat, 16 Jun 2012 23:37:24 +0200 Subject: [PATCH 01/24] contacts app now lists contacts sorted by expandable/collapsable addressbooks --- apps/contacts/css/contacts.css | 6 ++- apps/contacts/js/contacts.js | 34 +++++++-------- apps/contacts/templates/index.php | 6 +-- apps/contacts/templates/part.contacts.php | 53 ++++++++++++++++++----- 4 files changed, 66 insertions(+), 33 deletions(-) diff --git a/apps/contacts/css/contacts.css b/apps/contacts/css/contacts.css index dc16d9764c..0240207d79 100644 --- a/apps/contacts/css/contacts.css +++ b/apps/contacts/css/contacts.css @@ -2,9 +2,11 @@ font-weight: bold; }*/ #leftcontent { top: 3.5em !important; padding: 0; margin: 0; } +#leftcontent a { padding: 0 0 0 25px; } #rightcontent { top: 3.5em !important; padding-top: 5px; } -#contacts { background: #fff; width: 20em; left: 12.5em; top: 3.7em; bottom:3em; position: fixed; overflow: auto; padding: 0; margin: 0; } -#contacts a { height: 23px; display: block; margin: 0 0 0 0; padding: 0 0 0 25px; } +#leftcontent h3 {background: #aaa; display: block; max-width: 100%; height: 2em; padding: 0.5em 0.8em;} +.contacts { background: #fff; max-width: 100%; width: 20em; left: 12.5em; top: 3.7em; bottom:3em; overflow: auto; padding: 0; margin: 0; } +.contacts a { height: 23px; display: block; left: 12.5em; margin: 0 0 0 0; padding: 0 0 0 25px; } #bottomcontrols { padding: 0; bottom:0px; height:2.8em; width: 20em; margin:0; background:#eee; border-top:1px solid #ccc; position:fixed; -moz-box-shadow: 0 -3px 3px -3px #000; -webkit-box-shadow: 0 -3px 3px -3px #000; box-shadow: 0 -3px 3px -3px #000;} #contacts_newcontact { float: left; margin: 0.2em 0 0 1em; } #chooseaddressbook { float: right; margin: 0.2em 1em 0 0; } diff --git a/apps/contacts/js/contacts.js b/apps/contacts/js/contacts.js index a1b9976006..1c5139117d 100644 --- a/apps/contacts/js/contacts.js +++ b/apps/contacts/js/contacts.js @@ -173,11 +173,11 @@ Contacts={ // Name has changed. Update it and reorder. $('#fn').change(function(){ var name = $('#fn').val().strip_tags(); - var item = $('#contacts [data-id="'+Contacts.UI.Card.id+'"]'); + var item = $('.contacts [data-id="'+Contacts.UI.Card.id+'"]'); $(item).find('a').html(name); Contacts.UI.Card.fn = name; var added = false; - $('#contacts li').each(function(){ + $('.contacts li').each(function(){ if ($(this).text().toLowerCase() > name.toLowerCase()) { $(this).before(item).fadeIn('fast'); added = true; @@ -248,12 +248,12 @@ Contacts={ update:function(id) { var newid; if(!id) { - newid = $('#contacts li:first-child').data('id'); + newid = $('.contacts li:first-child').data('id'); } else { newid = id; } var localLoadContact = function(id) { - if($('#contacts li').length > 0) { + if($('.contacts li').length > 0) { $('#leftcontent li[data-id="'+newid+'"]').addClass('active'); $.getJSON(OC.filePath('contacts', 'ajax', 'contactdetails.php'),{'id':newid},function(jsondata){ if(jsondata.status == 'success'){ @@ -278,7 +278,7 @@ Contacts={ } }); } - else if($('#contacts li').length == 0) { + else if($('.contacts li').length == 0) { // load intro page $.getJSON(OC.filePath('contacts', 'ajax', 'loadintro.php'),{},function(jsondata){ if(jsondata.status == 'success'){ @@ -384,7 +384,7 @@ Contacts={ this.id = this.fn = this.fullname = this.shortname = this.famname = this.givname = this.addname = this.honpre = this.honsuf = ''; this.data = undefined; - if($('#contacts li').length > 0) { // Load first in list. + if($('.contacts li').length > 0) { // Load first in list. Contacts.UI.Card.update(newid); } else { // load intro page @@ -1498,7 +1498,7 @@ Contacts={ update:function(){ $.getJSON(OC.filePath('contacts', 'ajax', 'contacts.php'),{},function(jsondata){ if(jsondata.status == 'success'){ - $('#contacts').html(jsondata.data.page); + $('#leftcontent').html(jsondata.data.page); Contacts.UI.Card.update(); } else{ @@ -1506,8 +1506,8 @@ Contacts={ } }); setTimeout(function() { - $('#contacts li').unbind('inview'); - $('#contacts li').bind('inview', function(event, isInView, visiblePartX, visiblePartY) { + $('.contacts li').unbind('inview'); + $('.contacts li').bind('inview', function(event, isInView, visiblePartX, visiblePartY) { if (isInView) { if (!$(this).find('a').attr('style')) { $(this).find('a').css('background','url('+OC.filePath('contacts', '', 'thumbnail.php')+'?id='+$(this).data('id')+') no-repeat'); @@ -1518,19 +1518,19 @@ Contacts={ }, // Add thumbnails to the contact list as they become visible in the viewport. lazyupdate:function(){ - $('#contacts li').live('inview', function(){ + $('.contacts li').live('inview', function(){ if (!$(this).find('a').attr('style')) { $(this).find('a').css('background','url('+OC.filePath('contacts', '', 'thumbnail.php')+'?id='+$(this).data('id')+') no-repeat'); } }); }, refreshThumbnail:function(id){ - var item = $('#contacts [data-id="'+id+'"]').find('a'); + var item = $('.contacts [data-id="'+id+'"]').find('a'); item.html(Contacts.UI.Card.fn); item.css('background','url('+OC.filePath('contacts', '', 'thumbnail.php')+'?id='+id+'&refresh=1'+Math.random()+') no-repeat'); }, scrollTo:function(id){ - $('#contacts').animate({ + $('.contacts').animate({ scrollTop: $('#leftcontent li[data-id="'+id+'"]').offset().top-20}, 'slow','swing'); } } @@ -1552,12 +1552,12 @@ $(document).ready(function(){ $('#contacts_newcontact').keydown(Contacts.UI.Card.editNew); // Load a contact. - $('#contacts').keydown(function(event) { + $('.contacts').keydown(function(event) { if(event.which == 13) { - $('#contacts').click(); + $('.contacts').click(); } }); - $('#contacts').click(function(event){ + $('.contacts').click(function(event){ var $tgt = $(event.target); if ($tgt.is('li') || $tgt.is('a')) { var item = $tgt.is('li')?$($tgt):($tgt).parent(); @@ -1565,7 +1565,7 @@ $(document).ready(function(){ item.addClass('active'); var oldid = $('#rightcontent').data('id'); if(oldid != 0){ - $('#contacts li[data-id="'+oldid+'"]').removeClass('active'); + $('.contacts li[data-id="'+oldid+'"]').removeClass('active'); } $.getJSON(OC.filePath('contacts', 'ajax', 'contactdetails.php'),{'id':id},function(jsondata){ if(jsondata.status == 'success'){ @@ -1579,7 +1579,7 @@ $(document).ready(function(){ return false; }); - $('#contacts li').bind('inview', function(event, isInView, visiblePartX, visiblePartY) { + $('.contacts li').bind('inview', function(event, isInView, visiblePartX, visiblePartY) { if (isInView) { //NOTE: I've kept all conditions for future reference ;-) // element is now visible in the viewport if (visiblePartY == 'top') { diff --git a/apps/contacts/templates/index.php b/apps/contacts/templates/index.php index 7d212e71ba..82619601c2 100644 --- a/apps/contacts/templates/index.php +++ b/apps/contacts/templates/index.php @@ -3,10 +3,8 @@ var categories = ; var lang = ''; -
- +
+ inc("part.contacts"); ?>
diff --git a/apps/contacts/templates/part.contacts.php b/apps/contacts/templates/part.contacts.php index 5751750540..1e64119c05 100644 --- a/apps/contacts/templates/part.contacts.php +++ b/apps/contacts/templates/part.contacts.php @@ -1,12 +1,45 @@ -'.$addressbook_names[$i]['displayname'].''; + echo '
+
    '; + foreach($contacts[$addressbook_names[$i]['id']] as $contact): + $display = trim($contact['fullname']); + + if(!$display) { + $vcard = OC_Contacts_App::getContactVCard($contact['id']); + if(!is_null($vcard)) { + $struct = OC_Contacts_VCard::structureContact($vcard); + $display = isset($struct['EMAIL'][0])?$struct['EMAIL'][0]['value']:'[UNKNOWN]'; + } + } + echo '
  • '.htmlspecialchars($display).'
  • '; + + endforeach; + echo '
'; + } +} ?> -
  • - + From 92e35bd843890eabeb582c5b616354324f332e85 Mon Sep 17 00:00:00 2001 From: Stephan Bergemann Date: Sun, 17 Jun 2012 02:29:35 +0200 Subject: [PATCH 02/24] now a little less in template - more in ajax controller --- apps/contacts/ajax/contacts.php | 28 ++++++++++++- apps/contacts/js/contacts.js | 3 +- apps/contacts/templates/index.php | 1 - apps/contacts/templates/part.contacts.php | 51 ++++++++--------------- 4 files changed, 45 insertions(+), 38 deletions(-) diff --git a/apps/contacts/ajax/contacts.php b/apps/contacts/ajax/contacts.php index dbc9be5ca5..1edc35709e 100644 --- a/apps/contacts/ajax/contacts.php +++ b/apps/contacts/ajax/contacts.php @@ -11,9 +11,33 @@ OCP\JSON::checkLoggedIn(); OCP\JSON::checkAppEnabled('contacts'); $ids = OC_Contacts_Addressbook::activeIds(OCP\USER::getUser()); -$contacts = OC_Contacts_VCard::all($ids); +$contacts_alphabet = OC_Contacts_VCard::all($ids); +$active_addressbooks = OC_Contacts_Addressbook::active(OCP\USER::getUser()); + +// Our new array for the contacts sorted by addressbook +$contacts_addressbook = array(); +foreach($contacts_alphabet as $contact): + if(is_null($contacts_addressbook[$contact['addressbookid']])) { + $contacts_addressbook[$contact['addressbookid']] = array(); + } + $contacts_addressbook[$contact['addressbookid']][] = $contact; +endforeach; + +// FIXME: this is kind of ugly - just to replace the keys of the array +// perhaps we could do some magic combine_array() instead... +foreach($contacts_addressbook as $addressbook_id => $contacts): + foreach($active_addressbooks as $addressbook): + if($addressbook_id == $addressbook['id']) { + unset($contacts_addressbook[$addressbook_id]); + $contacts_addressbook[$addressbook['displayname']] = $contacts; + } + endforeach; +endforeach; +// This one should be ok for a small amount of Addressbooks +ksort($contacts_addressbook); + $tmpl = new OCP\Template("contacts", "part.contacts"); -$tmpl->assign('contacts', $contacts, false); +$tmpl->assign('contacts', $contacts_addressbook, false); $page = $tmpl->fetchPage(); OCP\JSON::success(array('data' => array( 'page' => $page ))); diff --git a/apps/contacts/js/contacts.js b/apps/contacts/js/contacts.js index 1c5139117d..925dbafe46 100644 --- a/apps/contacts/js/contacts.js +++ b/apps/contacts/js/contacts.js @@ -1557,7 +1557,7 @@ $(document).ready(function(){ $('.contacts').click(); } }); - $('.contacts').click(function(event){ + $(document).on("click", ".contacts",function(event){ var $tgt = $(event.target); if ($tgt.is('li') || $tgt.is('a')) { var item = $tgt.is('li')?$($tgt):($tgt).parent(); @@ -1678,3 +1678,4 @@ $(document).ready(function(){ $('#contacts_propertymenu_dropdown a').click(propertyMenuItem); $('#contacts_propertymenu_dropdown a').keydown(propertyMenuItem); }); +Contacts.UI.Contacts.update(); diff --git a/apps/contacts/templates/index.php b/apps/contacts/templates/index.php index 82619601c2..74dcf5149d 100644 --- a/apps/contacts/templates/index.php +++ b/apps/contacts/templates/index.php @@ -4,7 +4,6 @@ var lang = '';
    - inc("part.contacts"); ?>
    diff --git a/apps/contacts/templates/part.contacts.php b/apps/contacts/templates/part.contacts.php index 1e64119c05..6c1252debc 100644 --- a/apps/contacts/templates/part.contacts.php +++ b/apps/contacts/templates/part.contacts.php @@ -1,39 +1,22 @@ '.$addressbook_names[$i]['displayname'].''; - echo '
    -
      '; - foreach($contacts[$addressbook_names[$i]['id']] as $contact): - $display = trim($contact['fullname']); - - if(!$display) { - $vcard = OC_Contacts_App::getContactVCard($contact['id']); - if(!is_null($vcard)) { - $struct = OC_Contacts_VCard::structureContact($vcard); - $display = isset($struct['EMAIL'][0])?$struct['EMAIL'][0]['value']:'[UNKNOWN]'; - } +foreach($_['contacts'] as $category => $contacts): + echo '

      '.$category.'

      '; + echo '
      '; + echo '
        '; + foreach($contacts as $contact): + $display = trim($contact['fullname']); + if(!$display) { + $vcard = OC_Contacts_App::getContactVCard($contact['id']); + if(!is_null($vcard)) { + $struct = OC_Contacts_VCard::structureContact($vcard); + $display = isset($struct['EMAIL'][0])?$struct['EMAIL'][0]['value']:'[UNKNOWN]'; } - echo '
      • '.htmlspecialchars($display).'
      • '; - - endforeach; - echo '
      '; - } -} + } + echo '
    • '.htmlspecialchars($display).'
    • '; + endforeach; + echo '
    '; + echo '
    '; +endforeach; ?> From 5a8f4b87839baaeb3b557895cc89d58e19ad75ce Mon Sep 17 00:00:00 2001 From: Thomas Tanghus Date: Sun, 17 Jun 2012 20:23:20 +0200 Subject: [PATCH 08/24] Adjustments for inview handler etc. --- apps/contacts/js/contacts.js | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/apps/contacts/js/contacts.js b/apps/contacts/js/contacts.js index 925dbafe46..981af6f53a 100644 --- a/apps/contacts/js/contacts.js +++ b/apps/contacts/js/contacts.js @@ -1498,23 +1498,34 @@ Contacts={ update:function(){ $.getJSON(OC.filePath('contacts', 'ajax', 'contacts.php'),{},function(jsondata){ if(jsondata.status == 'success'){ - $('#leftcontent').html(jsondata.data.page); + $('#leftcontent').html(jsondata.data.page).ready(function() { + setTimeout(function() { + $('.contacts li').unbind('inview'); + $('.contacts li:visible').bind('inview', function(event, isInView, visiblePartX, visiblePartY) { + if (isInView) { + if (!$(this).find('a').attr('style')) { + $(this).find('a').css('background','url('+OC.filePath('contacts', '', 'thumbnail.php')+'?id='+$(this).data('id')+') no-repeat'); + } + } + })}, 100); + setTimeout(Contacts.UI.Contacts.lazyupdate, 500); + }); Contacts.UI.Card.update(); } else{ OC.dialogs.alert(jsondata.data.message, t('contacts', 'Error')); } }); - setTimeout(function() { + /*setTimeout(function() { $('.contacts li').unbind('inview'); - $('.contacts li').bind('inview', function(event, isInView, visiblePartX, visiblePartY) { + $('.contacts li:visible').bind('inview', function(event, isInView, visiblePartX, visiblePartY) { if (isInView) { if (!$(this).find('a').attr('style')) { $(this).find('a').css('background','url('+OC.filePath('contacts', '', 'thumbnail.php')+'?id='+$(this).data('id')+') no-repeat'); } } })}, 500); - setTimeout(Contacts.UI.Contacts.lazyupdate, 500); + setTimeout(Contacts.UI.Contacts.lazyupdate, 500);*/ }, // Add thumbnails to the contact list as they become visible in the viewport. lazyupdate:function(){ @@ -1557,7 +1568,7 @@ $(document).ready(function(){ $('.contacts').click(); } }); - $(document).on("click", ".contacts",function(event){ + $(document).on('click', '.contacts', function(event){ var $tgt = $(event.target); if ($tgt.is('li') || $tgt.is('a')) { var item = $tgt.is('li')?$($tgt):($tgt).parent(); @@ -1579,6 +1590,11 @@ $(document).ready(function(){ return false; }); + $(document).on('click', '.addressbook', function(event){ + $(this).next().toggle(); + return false; + }); + $('.contacts li').bind('inview', function(event, isInView, visiblePartX, visiblePartY) { if (isInView) { //NOTE: I've kept all conditions for future reference ;-) // element is now visible in the viewport From 9e4a41e9cb672234b3d96fc83c96f93a91a3fb59 Mon Sep 17 00:00:00 2001 From: Thomas Tanghus Date: Sun, 17 Jun 2012 21:34:56 +0200 Subject: [PATCH 09/24] Add effect on addressbook show/hide. --- apps/contacts/css/contacts.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/contacts/css/contacts.css b/apps/contacts/css/contacts.css index d617373742..77bfc54663 100644 --- a/apps/contacts/css/contacts.css +++ b/apps/contacts/css/contacts.css @@ -4,7 +4,7 @@ #leftcontent { top: 3.5em !important; padding: 0; margin: 0; } #leftcontent a { padding: 0 0 0 25px; } #rightcontent { top: 3.5em !important; padding-top: 5px; } -#leftcontent h3 { cursor: pointer; -moz-transition: background 300ms ease 0s; background: none no-repeat scroll 1em center #eee; border-bottom: 1px solid #ddd; border-top: 1px solid #fff; display: block; max-width: 100%; height: 2em; padding: 0.5em 0.8em; color: #666; text-shadow: 0 1px 0 #f8f8f8; font-size: 1.2em; } +#leftcontent h3 { cursor: pointer; -moz-transition: background 300ms ease 0s; background: none no-repeat scroll 1em center #eee; border-bottom: 1px solid #ddd; border-top: 1px solid #fff; display: block; max-width: 100%; padding: 0.5em 0.8em; color: #666; text-shadow: 0 1px 0 #f8f8f8; font-size: 1.2em; } #leftcontent h3:hover { background-color: #DBDBDB; border-bottom: 1px solid #CCCCCC; border-top: 1px solid #D4D4D4; color: #333333; } .contacts { background: #fff; max-width: 100%; width: 20em; left: 12.5em; top: 3.7em; bottom:3em; overflow: auto; padding: 0; margin: 0; } .contacts a { height: 23px; display: block; left: 12.5em; margin: 0 0 0 0; padding: 0 0 0 25px; } From fb700de4a40432f26209911548045390a10499b8 Mon Sep 17 00:00:00 2001 From: Thomas Tanghus Date: Sun, 17 Jun 2012 21:37:13 +0200 Subject: [PATCH 10/24] Add effect on addressbook show/hide. --- apps/contacts/js/contacts.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/contacts/js/contacts.js b/apps/contacts/js/contacts.js index 981af6f53a..110c383ac7 100644 --- a/apps/contacts/js/contacts.js +++ b/apps/contacts/js/contacts.js @@ -1591,7 +1591,7 @@ $(document).ready(function(){ }); $(document).on('click', '.addressbook', function(event){ - $(this).next().toggle(); + $(this).next().slideToggle(300); return false; }); From 46a771d2e6261fae20f2bcadb2355c05954920d4 Mon Sep 17 00:00:00 2001 From: Thomas Tanghus Date: Sun, 17 Jun 2012 21:47:15 +0200 Subject: [PATCH 11/24] Sort addressbooks. --- apps/contacts/ajax/contacts.php | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/apps/contacts/ajax/contacts.php b/apps/contacts/ajax/contacts.php index 773f027dc6..beed3f05d5 100644 --- a/apps/contacts/ajax/contacts.php +++ b/apps/contacts/ajax/contacts.php @@ -6,6 +6,13 @@ * See the COPYING-README file. */ +function cmp($a, $b) +{ + if ($a['displayname'] == $b['displayname']) { + return 0; + } + return ($a['displayname'] < $b['displayname']) ? -1 : 1; +} OCP\JSON::checkLoggedIn(); OCP\JSON::checkAppEnabled('contacts'); @@ -39,6 +46,8 @@ foreach($contacts_addressbook as $addressbook_id => $contacts) { } } +usort($contacts_addressbook, 'cmp'); + $tmpl = new OCP\Template("contacts", "part.contacts"); $tmpl->assign('books', $contacts_addressbook, false); $page = $tmpl->fetchPage(); From 7d84c4741c72e46cf9d07bbae97d515f54f9a2d7 Mon Sep 17 00:00:00 2001 From: Thomas Tanghus Date: Sun, 17 Jun 2012 21:50:49 +0200 Subject: [PATCH 12/24] Use uasort instead of usort. --- apps/contacts/ajax/contacts.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/contacts/ajax/contacts.php b/apps/contacts/ajax/contacts.php index beed3f05d5..bf4d5deb2e 100644 --- a/apps/contacts/ajax/contacts.php +++ b/apps/contacts/ajax/contacts.php @@ -46,7 +46,7 @@ foreach($contacts_addressbook as $addressbook_id => $contacts) { } } -usort($contacts_addressbook, 'cmp'); +uasort($contacts_addressbook, 'cmp'); $tmpl = new OCP\Template("contacts", "part.contacts"); $tmpl->assign('books', $contacts_addressbook, false); From 8337b30e433710ce0f9a7d8b24f23e0fab6fe381 Mon Sep 17 00:00:00 2001 From: Thomas Tanghus Date: Sun, 17 Jun 2012 23:09:25 +0200 Subject: [PATCH 13/24] Add thumbnail links so they are loaded when addressbook is expanded. --- apps/contacts/templates/part.contacts.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/contacts/templates/part.contacts.php b/apps/contacts/templates/part.contacts.php index d23a249b98..f0b14c8e5f 100644 --- a/apps/contacts/templates/part.contacts.php +++ b/apps/contacts/templates/part.contacts.php @@ -1,9 +1,9 @@ $addressbook) { echo '

    '.$addressbook['displayname'].'

    '; - echo '