diff --git a/apps/bookmarks/appinfo/migrate.php b/apps/bookmarks/appinfo/migrate.php index e7e572f52d..f1353f1887 100644 --- a/apps/bookmarks/appinfo/migrate.php +++ b/apps/bookmarks/appinfo/migrate.php @@ -40,8 +40,8 @@ class OC_Migration_Provider_Bookmarks extends OC_Migration_Provider{ $idmap = array(); while( $row = $results->fetchRow() ){ // Import each bookmark, saving its id into the map - $query = OCP\DB::prepare( "INSERT INTO *PREFIX*bookmarks(url, title, user_id, public, added, lastmodified) VALUES (?, ?, ?, ?, ?, ?)" ); - $query->execute( array( $row['url'], $row['title'], $this->uid, $row['public'], $row['added'], $row['lastmodified'] ) ); + $bookmarkquery = OCP\DB::prepare( "INSERT INTO *PREFIX*bookmarks(url, title, user_id, public, added, lastmodified) VALUES (?, ?, ?, ?, ?, ?)" ); + $bookmarkquery->execute( array( $row['url'], $row['title'], $this->uid, $row['public'], $row['added'], $row['lastmodified'] ) ); // Map the id $idmap[$row['id']] = OCP\DB::insertid(); } @@ -51,8 +51,8 @@ class OC_Migration_Provider_Bookmarks extends OC_Migration_Provider{ $results = $query->execute( array( $oldid ) ); while( $row = $results->fetchRow() ){ // Import the tags for this bookmark, using the new bookmark id - $query = OCP\DB::prepare( "INSERT INTO *PREFIX*bookmarks_tags(bookmark_id, tag) VALUES (?, ?)" ); - $query->execute( array( $newid, $row['tag'] ) ); + $tagquery = OCP\DB::prepare( "INSERT INTO *PREFIX*bookmarks_tags(bookmark_id, tag) VALUES (?, ?)" ); + $tagquery->execute( array( $newid, $row['tag'] ) ); } } // All done! 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/ajax/loadphoto.php b/apps/contacts/ajax/loadphoto.php index 61b5356edc..a35631055e 100644 --- a/apps/contacts/ajax/loadphoto.php +++ b/apps/contacts/ajax/loadphoto.php @@ -42,11 +42,5 @@ foreach($vcard->children as $property){ } } -$tmpl = new OCP\Template("contacts", "part.contactphoto"); -$tmpl->assign('id', $id); -if($refresh) { - $tmpl->assign('refresh', 1); -} -$page = $tmpl->fetchPage(); -OCP\JSON::success(array('data' => array('page'=>$page, 'checksum'=>$checksum))); -?> +OCP\JSON::success(array('data' => array('checksum'=>$checksum))); + diff --git a/apps/contacts/appinfo/migrate.php b/apps/contacts/appinfo/migrate.php index 1400cdf79d..cceb440617 100644 --- a/apps/contacts/appinfo/migrate.php +++ b/apps/contacts/appinfo/migrate.php @@ -40,19 +40,20 @@ class OC_Migration_Provider_Contacts extends OC_Migration_Provider{ $idmap = array(); while( $row = $results->fetchRow() ){ // Import each bookmark, saving its id into the map - $query = OCP\DB::prepare( "INSERT INTO *PREFIX*contacts_addressbooks (`userid`, `displayname`, `uri`, `description`, `ctag`) VALUES (?, ?, ?, ?, ?)" ); - $query->execute( array( $this->uid, $row['displayname'], $row['uri'], $row['description'], $row['ctag'] ) ); + $addressbookquery = OCP\DB::prepare( "INSERT INTO *PREFIX*contacts_addressbooks (`userid`, `displayname`, `uri`, `description`, `ctag`) VALUES (?, ?, ?, ?, ?)" ); + $addressbookquery->execute( array( $this->uid, $row['displayname'], $row['uri'], $row['description'], $row['ctag'] ) ); // Map the id $idmap[$row['id']] = OCP\DB::insertid(); } // Now tags foreach($idmap as $oldid => $newid){ + $query = $this->content->prepare( "SELECT * FROM contacts_cards WHERE addressbookid LIKE ?" ); $results = $query->execute( array( $oldid ) ); while( $row = $results->fetchRow() ){ // Import the tags for this bookmark, using the new bookmark id - $query = OCP\DB::prepare( "INSERT INTO *PREFIX*contacts_cards (`addressbookid`, `fullname`, `carddata`, `uri`, `lastmodified`) VALUES (?, ?, ?, ?, ?)" ); - $query->execute( array( $newid, $row['fullname'], $row['carddata'], $row['uri'], $row['lastmodified'] ) ); + $contactquery = OCP\DB::prepare( "INSERT INTO *PREFIX*contacts_cards (`addressbookid`, `fullname`, `carddata`, `uri`, `lastmodified`) VALUES (?, ?, ?, ?, ?)" ); + $contactquery->execute( array( $newid, $row['fullname'], $row['carddata'], $row['uri'], $row['lastmodified'] ) ); } } // All done! diff --git a/apps/contacts/css/contacts.css b/apps/contacts/css/contacts.css index 1766c28761..ce4daa1d3a 100644 --- a/apps/contacts/css/contacts.css +++ b/apps/contacts/css/contacts.css @@ -73,10 +73,10 @@ label:hover, dt:hover { color: #333; } .contactsection { position: relative; float: left; /*max-width: 40em;*/ padding: 0.5em; height: auto: border: thin solid lightgray;/* -webkit-border-radius: 0.5em; -moz-border-radius: 0.5em; border-radius: 0.5em; background-color: #f8f8f8;*/ } #cropbox { margin: auto; } -#contacts_details_photo_wrapper { min-width: 120px; } +#contacts_details_photo_wrapper { width: 200px; } #contacts_details_photo_wrapper.wait { opacity: 0.6; filter:alpha(opacity=0.6); z-index:1000; background: url('%webroot%/core/img/loading.gif') no-repeat center center; cursor: wait; } -#contacts_details_photo { border-radius: 0.5em; border: thin solid #bbb; margin: 0.3em; background: url('%webroot%/core/img/loading.gif') no-repeat center center; -moz-box-shadow: 0 1px 3px #777; -webkit-box-shadow: 0 1px 3px #777; box-shadow: 0 1px 3px #777; } -#contacts_details_photo:hover { background: #fff; cursor: default; } +.contacts_details_photo { border-radius: 0.5em; border: thin solid #bbb; margin: 0.3em; background: url('%webroot%/core/img/loading.gif') no-repeat center center; -moz-box-shadow: 0 1px 3px #777; -webkit-box-shadow: 0 1px 3px #777; box-shadow: 0 1px 3px #777; opacity: 1; } +.contacts_details_photo:hover { background: #fff; cursor: default; } #phototools { position:absolute; margin: 5px 0 0 10px; width:auto; height:22px; padding:0px; background-color:#fff; list-style-type:none; border-radius: 0.5em; -moz-box-shadow: 0 1px 3px #777; -webkit-box-shadow: 0 1px 3px #777; box-shadow: 0 1px 3px #777; } #phototools li { display: inline; } #phototools li a { float:left; cursor:pointer; width:22px; height:22px; opacity: 0.6; } diff --git a/apps/contacts/js/contacts.js b/apps/contacts/js/contacts.js index e5326ad880..9d41b70a31 100644 --- a/apps/contacts/js/contacts.js +++ b/apps/contacts/js/contacts.js @@ -144,6 +144,31 @@ Contacts={ $('#edit_name').click(function(){Contacts.UI.Card.editName()}); $('#edit_name').keydown(function(){Contacts.UI.Card.editName()}); + $('#phototools li a').click(function() { + $(this).tipsy('hide'); + }); + $('#contacts_details_photo_wrapper').hover( + function () { + $('#phototools').slideDown(200); + }, + function () { + $('#phototools').slideUp(200); + } + ); + $('#phototools').hover( + function () { + $(this).removeClass('transparent'); + }, + function () { + $(this).addClass('transparent'); + } + ); + $('#phototools .upload').click(function() { + $('#file_upload_start').trigger('click'); + }); + $('#phototools .cloud').click(function() { + OC.dialogs.filepicker(t('contacts', 'Select photo'), Contacts.UI.Card.cloudPhotoSelected, false, 'image', true); + }); /* Initialize the photo edit dialog */ $('#edit_photo_dialog').dialog({ autoOpen: false, modal: true, height: 'auto', width: 'auto' @@ -273,7 +298,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 +310,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 +366,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) { @@ -1105,25 +1134,6 @@ Contacts={ loadPhotoHandlers:function(){ $('#phototools li a').tipsy('hide'); $('#phototools li a').tipsy(); - $('#phototools li a').click(function() { - $(this).tipsy('hide'); - }); - $('#contacts_details_photo_wrapper').hover( - function () { - $('#phototools').slideDown(200); - }, - function () { - $('#phototools').slideUp(200); - } - ); - $('#phototools').hover( - function () { - $(this).removeClass('transparent'); - }, - function () { - $(this).addClass('transparent'); - } - ); if(this.data.PHOTO) { $('#phototools .delete').click(function() { $(this).tipsy('hide'); @@ -1134,16 +1144,12 @@ Contacts={ $(this).tipsy('hide'); Contacts.UI.Card.editCurrentPhoto(); }); + $('#phototools .delete').show(); + $('#phototools .edit').show(); } else { $('#phototools .delete').hide(); $('#phototools .edit').hide(); } - $('#phototools .upload').click(function() { - $('#file_upload_start').trigger('click'); - }); - $('#phototools .cloud').click(function() { - OC.dialogs.filepicker(t('contacts', 'Select photo'), Contacts.UI.Card.cloudPhotoSelected, false, 'image', true); - }); }, cloudPhotoSelected:function(path){ $.getJSON(OC.filePath('contacts', 'ajax', 'oc_photo.php'),{'path':path,'id':Contacts.UI.Card.id},function(jsondata){ @@ -1158,22 +1164,33 @@ Contacts={ }); }, loadPhoto:function(refresh){ + var self = this; + var refreshstr = (refresh?'&refresh=1'+Math.random():'') $('#phototools li a').tipsy('hide'); var wrapper = $('#contacts_details_photo_wrapper'); - wrapper.addClass('wait'); + wrapper.addClass('loading').addClass('wait'); + + var img = new Image(); + $(img).load(function () { + $('img.contacts_details_photo').remove() + $(this).addClass('contacts_details_photo').hide(); + wrapper.removeClass('loading').removeClass('wait'); + $(this).insertAfter($('#phototools')).fadeIn(); + }).error(function () { + // notify the user that the image could not be loaded + $(t('contacts','something went wrong.')).insertAfter($('#phototools')); + }).attr('src', OC.linkTo('contacts', 'photo.php')+'?id='+self.id+refreshstr); + $.getJSON(OC.filePath('contacts', 'ajax', 'loadphoto.php'),{'id':this.id, 'refresh': refresh},function(jsondata){ if(jsondata.status == 'success'){ $('#contacts_details_photo_wrapper').data('checksum', jsondata.data.checksum); - wrapper.html(jsondata.data.page).ready(function(){ wrapper.removeClass('wait').tipsy() }); Contacts.UI.Card.loadPhotoHandlers(); } else{ - wrapper.removeClass('wait'); OC.dialogs.alert(jsondata.data.message, t('contacts', 'Error')); } }); $('#file_upload_form').show(); - $('#contacts_propertymenu_dropdown a[data-type="PHOTO"]').parent().hide(); }, editCurrentPhoto:function(){ $.getJSON(OC.filePath('contacts', 'ajax', 'currentphoto.php'),{'id':this.id},function(jsondata){ @@ -1209,15 +1226,15 @@ Contacts={ var target = $('#crop_target'); var form = $('#cropform'); var wrapper = $('#contacts_details_photo_wrapper'); + var self = this; wrapper.addClass('wait'); form.submit(); target.load(function(){ var response=jQuery.parseJSON(target.contents().text()); if(response != undefined && response.status == 'success'){ // load cropped photo. - wrapper.html(response.data.page).ready(function(){ wrapper.removeClass('wait') }); + self.loadPhoto(true); Contacts.UI.Card.data.PHOTO = true; - Contacts.UI.Card.loadPhotoHandlers(); }else{ OC.dialogs.alert(response.data.message, t('contacts', 'Error')); wrapper.removeClass('wait'); @@ -1532,6 +1549,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 +1581,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 +1714,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); diff --git a/apps/contacts/templates/part.contact.php b/apps/contacts/templates/part.contact.php index 5757563fe5..bb574372e5 100644 --- a/apps/contacts/templates/part.contact.php +++ b/apps/contacts/templates/part.contact.php @@ -18,7 +18,14 @@ $id = isset($_['id']) ? $_['id'] : '';
    +
    +
    @@ -104,7 +111,6 @@ $id = isset($_['id']) ? $_['id'] : '';