diff --git a/apps/contacts/ajax/contacts.php b/apps/contacts/ajax/contacts.php index 07b442159c..67ebcaf736 100644 --- a/apps/contacts/ajax/contacts.php +++ b/apps/contacts/ajax/contacts.php @@ -17,24 +17,44 @@ function cmp($a, $b) OCP\JSON::checkLoggedIn(); OCP\JSON::checkAppEnabled('contacts'); -$active_addressbooks = OC_Contacts_Addressbook::active(OCP\USER::getUser()); +$start = isset($_GET['startat'])?$_GET['startat']:0; +$aid = isset($_GET['aid'])?$_GET['aid']:null; +if(is_null($aid)) { + // Called initially to get the active addressbooks. + $active_addressbooks = OC_Contacts_Addressbook::active(OCP\USER::getUser()); +} else { + // called each time more contacts has to be shown. + $active_addressbooks = array(OC_Contacts_Addressbook::find($aid)); +} + + +session_write_close(); + +// create the addressbook associate array $contacts_addressbook = array(); $ids = array(); foreach($active_addressbooks as $addressbook) { $ids[] = $addressbook['id']; if(!isset($contacts_addressbook[$addressbook['id']])) { - $contacts_addressbook[$addressbook['id']] = array('contacts' => array()); + $contacts_addressbook[$addressbook['id']] = array('contacts' => array('type' => 'book',)); $contacts_addressbook[$addressbook['id']]['displayname'] = $addressbook['displayname']; } } -$contacts_alphabet = OC_Contacts_VCard::all($ids); +$contacts_alphabet = array(); + +// get next 50 for each addressbook. +foreach($ids as $id) { + if($id) { + $contacts_alphabet = array_merge($contacts_alphabet, OC_Contacts_VCard::all($id, $start, 50)); + } +} // Our new array for the contacts sorted by addressbook if($contacts_alphabet) { foreach($contacts_alphabet as $contact) { if(!isset($contacts_addressbook[$contact['addressbookid']])) { // It should never execute. - $contacts_addressbook[$contact['addressbookid']] = array('contacts' => array()); + $contacts_addressbook[$contact['addressbookid']] = array('contacts' => array('type' => 'book',)); } $display = trim($contact['fullname']); if(!$display) { @@ -44,15 +64,11 @@ if($contacts_alphabet) { $display = isset($struct['EMAIL'][0])?$struct['EMAIL'][0]['value']:'[UNKNOWN]'; } } - $contacts_addressbook[$contact['addressbookid']]['contacts'][] = array('id' => $contact['id'], 'addressbookid' => $contact['addressbookid'], 'displayname' => htmlspecialchars($display)); + $contacts_addressbook[$contact['addressbookid']]['contacts'][] = array('type' => 'contact', 'id' => $contact['id'], 'addressbookid' => $contact['addressbookid'], 'displayname' => htmlspecialchars($display)); } } unset($contacts_alphabet); uasort($contacts_addressbook, 'cmp'); -$tmpl = new OCP\Template("contacts", "part.contacts"); -$tmpl->assign('books', $contacts_addressbook, false); -$page = $tmpl->fetchPage(); - -OCP\JSON::success(array('data' => array( 'page' => $page ))); +OCP\JSON::success(array('data' => array('entries' => $contacts_addressbook))); diff --git a/apps/contacts/js/contacts.js b/apps/contacts/js/contacts.js index e5326ad880..d357e50608 100644 --- a/apps/contacts/js/contacts.js +++ b/apps/contacts/js/contacts.js @@ -273,7 +273,7 @@ Contacts={ update:function(id, bookid) { var newid, firstitem; if(!id) { - firstitem = $('#contacts:first-child li:first-child'); + firstitem = $('#contacts ul').first().find('li:first-child'); if(firstitem.length > 0) { newid = firstitem.data('id'); bookid = firstitem.data('bookid'); @@ -285,6 +285,7 @@ Contacts={ if(!bookid) { bookid = $('#contacts h3').first().data('id'); } + console.log('bookid: ' +bookid); var localLoadContact = function(newid, bookid) { if($('.contacts li').length > 0) { $('#contacts li[data-id="'+newid+'"]').addClass('active'); @@ -340,6 +341,9 @@ Contacts={ Contacts.UI.Card.add(';;;;;', '', '', true); return false; }, + createEntry:function(data) { + return $('
  • '+data.displayname+'
  • '); + }, add:function(n, fn, aid, isnew){ // add a new contact aid = aid?aid:$('#contacts h3.active').first().data('id'); var localAddcontact = function(n, fn, aid, isnew) { @@ -1532,6 +1536,7 @@ Contacts={ } }, Contacts:{ + batchnum:50, drop:function(event, ui) { var dragitem = ui.draggable, droptarget = $(this); //console.log('Drop ' + dragitem.data('id') +' on: ' + droptarget.data('id')); @@ -1563,64 +1568,79 @@ Contacts={ }); }, // Reload the contacts list. - update:function(id){ - $.getJSON(OC.filePath('contacts', 'ajax', 'contacts.php'),{},function(jsondata){ + update:function(id, aid, start){ + self = this; + console.log('update: ' + aid + ' ' + start); + var firstrun = false; + var opts = {}; + opts['startat'] = (start?start:0); + if(aid) { + opts['aid'] = aid; + } + $.getJSON(OC.filePath('contacts', 'ajax', 'contacts.php'),opts,function(jsondata){ if(jsondata.status == 'success'){ - $('#contacts').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'); - } + var books = jsondata.data.entries; + $.each(jsondata.data.entries, function(b, book) { + if($('#contacts h3[data-id="'+b+'"]').length == 0) { + firstrun = true; + + if($('#contacts h3').length == 0) { + $('#contacts').html('

    '+book.displayname+'

    '); + } else { + if(!$('#contacts h3[data-id="'+b+'"]').length) { + $('

    '+book.displayname+'

    ') + .appendTo('#contacts'); } - })}, 100); - setTimeout(Contacts.UI.Contacts.lazyupdate, 500);*/ - if($('#contacts h3').length > 1) { - $('#contacts h3,#contacts ul').each(function(index) { - var id = $(this).data('id'); - var accept = 'li:not([data-bookid="'+id+'"])'; - $(this).droppable({ - drop: Contacts.UI.Contacts.drop, - activeClass: 'ui-state-hover', - accept: accept + } + $('#contacts h3[data-id="'+b+'"]').on('click', function(event) { + $('#contacts h3').removeClass('active'); + $(this).addClass('active'); + $('#contacts ul[data-id="'+b+'"]').slideToggle(300); + return false; + }); + var accept = 'li:not([data-bookid="'+b+'"])'; + $('#contacts h3[data-id="'+b+'"]').droppable({ + drop: Contacts.UI.Contacts.drop, + activeClass: 'ui-state-hover', + accept: accept + }); + } + var contactlist = $('#contacts ul[data-id="'+b+'"]'); + for(var c in book.contacts) { + if(book.contacts[c].id == undefined) { continue; } + var contact = Contacts.UI.Card.createEntry(book.contacts[c]); + if(c == self.batchnum-5) { + contact.bind('inview', function(event, isInView, visiblePartX, visiblePartY) { + $(this).unbind(event); + var bookid = $(this).data('bookid'); + var numsiblings = $('.contacts li[data-bookid="'+bookid+'"]').length; + if (isInView && numsiblings >= self.batchnum) { + console.log('This would be a good time to load more contacts.'); + Contacts.UI.Contacts.update(id, bookid, $('#contacts li[data-bookid="'+bookid+'"]').length); + } }); - }); - $('#contacts li').draggable({ - revert: 'invalid', - axis: 'y', containment: '#contacts', - scroll: true, scrollSensitivity: 100, - opacity: 0.7, helper: 'clone' - }); - } else { - $('#contacts h3').first().addClass('active'); + } + contactlist.append(contact); } }); - Contacts.UI.Card.update(id); + if($('#contacts h3').length > 1) { + $('#contacts li').draggable({ + revert: 'invalid', + axis: 'y', containment: '#contacts', + scroll: true, scrollSensitivity: 100, + opacity: 0.7, helper: 'clone' + }); + } else { + $('#contacts h3').first().addClass('active'); + } + if(opts['startat'] == 0) { // only update card on first load. + Contacts.UI.Card.update(); + } } else{ OC.dialogs.alert(jsondata.data.message, t('contacts', 'Error')); } }); - /*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'); - } - } - })}, 500); - setTimeout(Contacts.UI.Contacts.lazyupdate, 500);*/ - }, - // Add thumbnails to the contact list as they become visible in the viewport. - lazyupdate: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 li[data-id="'+id+'"]').find('a'); @@ -1681,13 +1701,6 @@ $(document).ready(function(){ return false; }); - $(document).on('click', '.addressbook', function(event){ - $('#contacts h3').removeClass('active'); - $(this).addClass('active'); - $(this).next().slideToggle(300); - 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 diff --git a/apps/contacts/lib/vcard.php b/apps/contacts/lib/vcard.php index bf22be0de7..e3b6560562 100644 --- a/apps/contacts/lib/vcard.php +++ b/apps/contacts/lib/vcard.php @@ -47,11 +47,18 @@ class OC_Contacts_VCard{ * The cards are associative arrays. You'll find the original vCard in * ['carddata'] */ - public static function all($id){ + public static function all($id, $start=null, $num=null){ + $limitsql = ''; + if(!is_null($num)) { + $limitsql = ' LIMIT '.$num; + } + if(!is_null($start) && !is_null($num)) { + $limitsql .= ' OFFSET '.$start.' '; + } $result = null; if(is_array($id) && count($id)) { $id_sql = join(',', array_fill(0, count($id), '?')); - $prep = 'SELECT * FROM *PREFIX*contacts_cards WHERE addressbookid IN ('.$id_sql.') ORDER BY fullname'; + $prep = 'SELECT * FROM *PREFIX*contacts_cards WHERE addressbookid IN ('.$id_sql.') ORDER BY fullname '.$limitsql; try { $stmt = OCP\DB::prepare( $prep ); $result = $stmt->execute($id); @@ -63,7 +70,8 @@ class OC_Contacts_VCard{ } } elseif(is_int($id) || is_string($id)) { try { - $stmt = OCP\DB::prepare( 'SELECT * FROM *PREFIX*contacts_cards WHERE addressbookid = ? ORDER BY fullname' ); + $sql = 'SELECT * FROM *PREFIX*contacts_cards WHERE addressbookid = ? ORDER BY fullname'.$limitsql; + $stmt = OCP\DB::prepare( $sql ); $result = $stmt->execute(array($id)); } catch(Exception $e) { OCP\Util::writeLog('contacts',__CLASS__.'::'.__METHOD__.', exception: '.$e->getMessage(),OCP\Util::ERROR);