From 05de0b35a4f36c37f1389edf61944907ec9f86a4 Mon Sep 17 00:00:00 2001 From: Maksim Pecherskiy Date: Thu, 6 Mar 2014 14:38:07 -0800 Subject: [PATCH] Stabilizing ajax loads. --- app.js | 1 + controllers/note.js | 21 +++++- public/js/main.js | 164 ++++++++++++++++++++++++++------------------ views/home.jade | 1 + 4 files changed, 119 insertions(+), 68 deletions(-) diff --git a/app.js b/app.js index 0119375..0a98adc 100755 --- a/app.js +++ b/app.js @@ -104,6 +104,7 @@ app.use(express.errorHandler()); app.get('/', homeController.index); app.get('/note/new', noteController.getNewNoteForm); app.post('/note/new', noteController.postNewNoteForm); +app.get('/notes/:skip/:limit', noteController.getNotes); app.get('/login', userController.getLogin); app.post('/login', userController.postLogin); app.get('/logout', userController.logout); diff --git a/controllers/note.js b/controllers/note.js index d4b1cfc..8f4f130 100644 --- a/controllers/note.js +++ b/controllers/note.js @@ -62,9 +62,26 @@ exports.saveNote = function(noteData, callback) { }; -exports.getNotes = function(requestParams) { +/** + * GET /notes/:skip/:limit + * Get Notes. + * @param req + * @param res + */ + +exports.getNotes = function(req, res) { console.log('getnotes'); + console.log(req.params); + var requestParams = {}; + var requestParams = {skip: req.params.skip, limit: req.params.limit}; + // TODO validate params incoming. + console.log(requestParams); // @TODO -- use select here to figure out unneeded params. - return Note.find(null, null, requestParams).sort({ _id: -1 }).exec(); + Note.find(null, null, requestParams).sort({ _id: -1 }).exec(function(err, foundNotes){ + res.send({ + requestParams: requestParams, + notes: foundNotes + }); + }); }; diff --git a/public/js/main.js b/public/js/main.js index 6ec654a..f69cd76 100644 --- a/public/js/main.js +++ b/public/js/main.js @@ -1,14 +1,15 @@ // @TODO most of this stuff is home page specific. Make it only load to front page. -$(document).ready(function() { - var container = $('.notes'); - var errorFlashContainer = $('#flash'); - var flashElement = $('.new-content-flash'); - var flashInAnimationName = 'fadeInDown'; - var flashOutAnimationName = 'fadeOut'; - var noteIncrementLoadLimit = 27; - - // Helpers. - var templateNote = function(noteData) { + +var prLover = { + container: 'ul.notes', + errorFlashContainer: $('#flash'), + flashElement: $('.new-content-flash'), + flashInAnimationName: 'fadeInDown', + flashOutAnimationName: 'fadeOut', + noteIncrementLoadLimit: 27, + flashFinishedEvents: 'webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend', + + templateNote: function(noteData) { // Template the new note. var newNote = "
  • " + noteData.text + "
    "; if (noteData.twitterHandle) { @@ -17,76 +18,107 @@ $(document).ready(function() { newNote = newNote + "
  • "; return newNote; - }; + }, - var getDocHeight = function() { + getDocHeight: function() { var D = document; return Math.max( Math.max(D.body.scrollHeight, D.documentElement.scrollHeight), Math.max(D.body.offsetHeight, D.documentElement.offsetHeight), Math.max(D.body.clientHeight, D.documentElement.clientHeight) ); - } - - var requestNotes = function() { - var noteRequestParams = {skip: container.data('loadedNotes'), limit: noteIncrementLoadLimit}; - console.log(noteRequestParams); - socket.emit('additionalNotesRequested', noteRequestParams); - }; - - container.data('loadedNotes', 0); - $(window).bind('scroll', function() { - if($(window).scrollTop() + $(window).height() == getDocHeight()) { - console.log("bottom!"); - requestNotes(); - } - }); - - // Setup Stuff. - // The notes there initially will always show up so we can be sure about it. - // TODO -- look into socket loading in the beginning -- with not db call by load at all. - /*container.data('loadedNotes', 0); - container.bind('inview', function(event, isInView, visiblePartX, visiblePartY) { - console.log('Bind Fire.'); - console.log('isInView: ' + isInView); - console.log('visiblePartY: ' + visiblePartY); - if (isInView && (visiblePartY == 'bottom' || visiblePartY == 'both')) { - console.log('Gonna load some stuff'); - var noteRequestParams = {skip: container.data('loadedNotes'), limit: noteIncrementLoadLimit}; - console.log(noteRequestParams); - socket.emit('additionalNotesRequested', noteRequestParams); - } - });*/ - - // Bind to the flash element that every time the animation is over, to clear the animate.css classes. - var fadeOutBinding = function () { + }, + fadeOut: function (element) { console.log('fading out.'); // React differently based on in our out animation; - if ($(this).hasClass(flashOutAnimationName)) { + if ($(element).hasClass(flashOutAnimationName)) { // Clear html on flash out. console.log('flashout'); - $(this).html(''); + $(element).html(''); } // Regardless remove animation classes. - $(this).removeClass('animated ' + flashInAnimationName); - $(this).removeClass('animated ' + flashOutAnimationName); - }; + $(element).removeClass('animated ' + flashInAnimationName); + $(element).removeClass('animated ' + flashOutAnimationName); + }, + + getNotes: function(options) { + console.log('Get Notes Options'); + console.log(options); + var url = 'notes/' + options.skip + '/' + options.limit; + return $.ajax({ + type: "GET", + url: url, + dataType: 'json', + }); + }, + insertNewNotes: function(newNoteData) { + console.log('Insert New Notes'); + console.log(newNoteData); + // First Time Call. + if (!newNoteData.requestParams.skip || newNoteData.requestParams.skip < 1) { + $(this.container).isotope({ + itemSelector: '.note', + // options... + resizable: false, // disable normal resizing + // set columnWidth to a percentage of container width + masonry: { columnWidth: $(this.container).width() / 50 } + }); + } + // Last Time Call. + if (newNoteData.notes.length < 1) { + console.log('Unbind InView'); + //container.unbind('inview'); + $(window).unbind('scroll'); + return; + } + // Insert notes as needed. - $(errorFlashContainer).bind('webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend', fadeOutBinding); - $(flashElement).bind('webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend', fadeOutBinding); + var notesToAdd = ''; + for (var i = 0; i < newNoteData.notes.length; i++) { + notesToAdd = notesToAdd + this.templateNote(newNoteData.notes[i]); + } + $(this.container).isotope('insert', $(notesToAdd)); + var updatedNoteCount = $(this.container).data('loadedNotes') + this.noteIncrementLoadLimit; + $(this.container).data('loadedNotes', updatedNoteCount); + }, + + init: function() { + // Setup. + // Grab Loaded Notes + var self = this; + $(this.container).data('loadedNotes', 0); + // Bind Scroll Loading. + $(window).bind('scroll', function() { + if ($(window).scrollTop() + $(window).height() == self.getDocHeight()) { + console.log("bottom!"); + self.getNotes({ + skip: $(self.container).data('loadedNotes'), + limit: self.noteIncrementLoadLimit + }).then(function(noteData) { + self.insertNewNotes(noteData); + }); + } + }); + // Bind Flash Finished Events. + $(this.errorFlashContainer).bind(this.flashFinishedEvent, this.fadeOut); + $(this.flashElement).bind(this.flashFinishedEvent, this.fadeOut); + + this.getNotes({ + skip: $(this.container).data('loadedNotes'), + limit: this.noteIncrementLoadLimit + }).then(function(noteData) { + self.insertNewNotes(noteData); + }); + } +}; - // Socket Ops. - var socket = io.connect(); - socket.on('connect', function() { - console.log('CLIENT: Connection Made'); - var noteRequestParams = {skip: container.data('loadedNotes'), limit: noteIncrementLoadLimit}; - socket.emit('additionalNotesRequested', noteRequestParams); - }); +$(document).ready(function() { + prLover.init(); - socket.on('appFlash', function(flashData) { + /* socket.on('appFlash', function(flashData) { var flashString = ''; for (var i = 0; i < flashData.length; i++) { flashString = flashString + '
    ' + flashData[i].message + '
    '; @@ -95,9 +127,9 @@ $(document).ready(function() { setTimeout(function() { $(errorFlashContainer).addClass('animated ' + flashOutAnimationName); }, 500); - }); + });*/ - socket.on('additionalNotesLoaded', function(newNoteData) { + /*socket.on('additionalNotesLoaded', function(newNoteData) { if (!newNoteData.requestParams.skip || newNoteData.requestParams.skip < 1) { container.isotope({ itemSelector: '.note', @@ -122,9 +154,9 @@ $(document).ready(function() { var updatedNoteCount = container.data('loadedNotes') + noteIncrementLoadLimit; container.data('loadedNotes', updatedNoteCount); - }); + });*/ - socket.on('newNoteSaved', function(data) { + /*socket.on('newNoteSaved', function(data) { // @TODO how to template this? // Get Current "Unread" Note Count var noteCount = $('.new-content-flash').data('note-count') || 0; @@ -169,7 +201,7 @@ $(document).ready(function() { return false; }); }); - +*/ // @TODO Should this just be ajax? diff --git a/views/home.jade b/views/home.jade index e404732..e087344 100644 --- a/views/home.jade +++ b/views/home.jade @@ -20,6 +20,7 @@ block content | Enviar .new-content-flash ul.notes + //img(src="http://www.ajaxload.info/cache/FF/FF/FF/34/7C/DF/27-1.gif") // for note in notes // li.note // .note-text= note.text