From e802d00996d6948e29f085d4de9409423e0d91a4 Mon Sep 17 00:00:00 2001 From: Riyad Preukschas Date: Fri, 14 Sep 2012 16:52:24 +0200 Subject: [PATCH] Completely redo loading of notes with JS --- app/assets/javascripts/note.js | 199 ++++++++++++++----------- app/contexts/notes/load_context.rb | 9 +- app/helpers/notes_helper.rb | 9 ++ app/views/notes/_create_common.js.haml | 3 +- app/views/notes/_load.js.haml | 14 +- 5 files changed, 134 insertions(+), 100 deletions(-) create mode 100644 app/helpers/notes_helper.rb diff --git a/app/assets/javascripts/note.js b/app/assets/javascripts/note.js index 47b0e0f5..ccc84ac9 100644 --- a/app/assets/javascripts/note.js +++ b/app/assets/javascripts/note.js @@ -4,9 +4,8 @@ var NoteList = { target_params: null, target_id: 0, target_type: null, - first_id: 0, - last_id: 0, - disable:false, + bottom_id: 0, + loading_more_disabled: false, init: function(tid, tt, path) { @@ -15,26 +14,23 @@ var NoteList = { this.target_type = tt; this.target_params = "&target_type=" + this.target_type + "&target_id=" + this.target_id; - // get notes + // get initial set of notes this.getContent(); - // get new notes every n seconds - this.initRefresh(); - $('.delete-note').live('ajax:success', function() { $(this).closest('li').fadeOut(); }); - $(".note-form-holder").live("ajax:before", function(){ + $(".note-form-holder").on("ajax:before", function(){ $(".submit_note").disable() }) - $(".note-form-holder").live("ajax:complete", function(){ + $(".note-form-holder").on("ajax:complete", function(){ $(".submit_note").enable() }) disableButtonIfEmptyField(".note-text", ".submit_note"); - $(".note-text").live("focus", function(){ + $(".note-text").on("focus", function(){ $(this).css("height", "80px"); $('.note_advanced_opts').show(); }); @@ -44,64 +40,20 @@ var NoteList = { var filename = val.replace(/^.*[\\\/]/, ''); $(".file_name").text(filename); }); - }, /** - * Load new notes to fresh list called 'new_notes_list': - * - Replace 'new_notes_list' with new list every n seconds - * - Append new notes to this list after submit + * Handle loading the initial set of notes. + * And set up loading more notes when scrolling to the bottom of the page. */ - initRefresh: - function() { - // init timer - var intNew = setInterval("NoteList.getNew()", 10000); - }, - - replace: - function(html) { - $("#new_notes_list").html(html); - }, - - prepend: - function(id, html) { - if(id != this.last_id) { - $("#new_notes_list").prepend(html); - } - }, - - getNew: - function() { - // refersh notes list - $.ajax({ - type: "GET", - url: this.notes_path, - data: "last_id=" + this.last_id + this.target_params, - dataType: "script"}); - }, - - refresh: - function() { - // refersh notes list - $.ajax({ - type: "GET", - url: this.notes_path, - data: "first_id=" + this.first_id + "&last_id=" + this.last_id + this.target_params, - dataType: "script"}); - }, - /** - * Init load of notes: - * 1. Get content with ajax call - * 2. Set content of notes list with loaded one + * Gets an inital set of notes. */ - - - getContent: - function() { + getContent: + function() { $.ajax({ type: "GET", url: this.notes_path, @@ -111,10 +63,13 @@ var NoteList = { dataType: "script"}); }, + /** + * Called in response to getContent(). + * Replaces the content of #notes-list with the given html. + */ setContent: - function(fid, lid, html) { - this.last_id = lid; - this.first_id = fid; + function(last_id, html) { + this.bottom_id = last_id; $("#notes-list").html(html); // Init infinite scrolling @@ -123,54 +78,126 @@ var NoteList = { /** - * Paging for old notes when scroll to bottom: - * 1. Init scroll events with 'initLoadMore' - * 2. Load onlder notes with 'getOld' method - * 3. append old notes to bottom of list with 'append' + * Handle loading more notes when scrolling to the bottom of the page. + * The id of the last note in the list is in this.bottom_id. * + * Set up refreshing only new notes after all notes have been loaded. */ - getOld: + + + /** + * Initializes loading more notes when scrolling to the bottom of the page. + */ + initLoadMore: function() { + $(document).endlessScroll({ + bottomPixels: 400, + fireDelay: 1000, + fireOnce:true, + ceaseFire: function() { + return NoteList.loading_more_disabled; + }, + callback: function(i) { + NoteList.getMore(); + } + }); + }, + + /** + * Gets an additional set of notes. + */ + getMore: + function() { + // only load more notes if there are no "new" notes $('.loading').show(); $.ajax({ type: "GET", url: this.notes_path, - data: "first_id=" + this.first_id + this.target_params, + data: "loading_more=1&after_id=" + this.bottom_id + this.target_params, complete: function(){ $('.notes-status').removeClass("loading")}, beforeSend: function() { $('.notes-status').addClass("loading") }, dataType: "script"}); }, - append: + /** + * Called in response to getMore(). + * Append notes to #notes-list. + */ + appendMoreNotes: function(id, html) { - if(this.first_id == id) { - this.disable = true; - } else { - this.first_id = id; + if(id != this.bottom_id) { + this.bottom_id = id; $("#notes-list").append(html); } }, - initLoadMore: + /** + * Called in response to getMore(). + * Disables loading more notes when scrolling to the bottom of the page. + * Initalizes refreshing new notes. + */ + finishedLoadingMore: function() { - $(document).endlessScroll({ - bottomPixels: 400, - fireDelay: 1000, - fireOnce:true, - ceaseFire: function() { - return NoteList.disable; - }, - callback: function(i) { - NoteList.getOld(); + this.loading_more_disabled = true; + + // from now on only get new notes + this.initRefreshNew(); + }, + + + /** + * Handle refreshing and adding of new notes. + * + * New notes are all notes that are created after the site has been loaded. + * The "old" notes are in #notes-list the "new" ones will be in #new-notes-list. + * The id of the last "old" note is in this.bottom_id. + */ + + + /** + * Initializes getting new notes every n seconds. + */ + initRefreshNew: + function() { + setInterval("NoteList.getNew()", 10000); + }, + + /** + * Gets the new set of notes (i.e. all notes after ). + */ + getNew: + function() { + $.ajax({ + type: "GET", + url: this.notes_path, + data: "loading_new=1&after_id=" + this.bottom_id + this.target_params, + dataType: "script"}); + }, + + /** + * Called in response to getNew(). + * Replaces the content of #new-notes-list with the given html. + */ + replaceNewNotes: + function(html) { + $("#new-notes-list").html(html); + }, + + /** + * Adds a single note to #new-notes-list. + */ + appendNewNote: + function(id, html) { + if(id != this.bottom_id) { + $("#new-notes-list").append(html); } - }); } }; -var PerLineNotes = { +var PerLineNotes = { init: function() { - $(".line_note_link, .line_note_reply_link").live("click", function(e) { + $(".line_note_link, .line_note_reply_link").on("click", function(e) { var form = $(".per_line_form"); $(this).closest("tr").after(form); form.find("#note_line_code").val($(this).attr("line_code")); diff --git a/app/contexts/notes/load_context.rb b/app/contexts/notes/load_context.rb index c026fc50..c2d7644b 100644 --- a/app/contexts/notes/load_context.rb +++ b/app/contexts/notes/load_context.rb @@ -3,8 +3,7 @@ module Notes def execute target_type = params[:target_type] target_id = params[:target_id] - first_id = params[:first_id] - last_id = params[:last_id] + after_id = params[:after_id] @notes = case target_type @@ -23,10 +22,8 @@ module Notes project.wikis.reverse.map {|w| w.notes.fresh }.flatten[0..20] end - @notes = if last_id - @notes.where("id < ?", last_id) - elsif first_id - @notes.where("id > ?", first_id) + @notes = if after_id + @notes.where("id > ?", after_id) else @notes end diff --git a/app/helpers/notes_helper.rb b/app/helpers/notes_helper.rb new file mode 100644 index 00000000..28701661 --- /dev/null +++ b/app/helpers/notes_helper.rb @@ -0,0 +1,9 @@ +module NotesHelper + def loading_more_notes? + params[:loading_more].present? + end + + def loading_new_notes? + params[:loading_new].present? + end +end diff --git a/app/views/notes/_create_common.js.haml b/app/views/notes/_create_common.js.haml index e80eccb1..ce678585 100644 --- a/app/views/notes/_create_common.js.haml +++ b/app/views/notes/_create_common.js.haml @@ -5,7 +5,8 @@ $('.note-form-holder #preview-link').text('Preview'); $('.note-form-holder #preview-note').hide(); $('.note-form-holder').show(); - NoteList.prepend(#{note.id}, "#{escape_javascript(render partial: "notes/show", locals: {note: note})}"); + NoteList.appendNewNote(#{note.id}, "#{escape_javascript(render "notes/show", note: note)}"); + - else :plain $(".note-form-holder").replaceWith("#{escape_javascript(render('form'))}"); diff --git a/app/views/notes/_load.js.haml b/app/views/notes/_load.js.haml index c16a699a..8c735476 100644 --- a/app/views/notes/_load.js.haml +++ b/app/views/notes/_load.js.haml @@ -1,17 +1,17 @@ - unless @notes.blank? - - if params[:last_id] + - if loading_more_notes? :plain - NoteList.replace("#{escape_javascript(render(partial: 'notes/notes_list'))}"); + NoteList.appendMoreNotes(#{@notes.last.id}, "#{escape_javascript(render 'notes/notes_list')}"); - - elsif params[:first_id] + - elsif loading_new_notes? :plain - NoteList.append(#{@notes.last.id}, "#{escape_javascript(render(partial: 'notes/notes_list'))}"); + NoteList.replaceNewNotes("#{escape_javascript(render 'notes/notes_list')}"); - else :plain - NoteList.setContent(#{@notes.last.id}, #{@notes.first.id}, "#{escape_javascript(render(partial: 'notes/notes_list'))}"); + NoteList.setContent(#{@notes.last.id}, "#{escape_javascript(render 'notes/notes_list')}"); - else - - if params[:first_id] + - if loading_more_notes? :plain - NoteList.append(#{params[:first_id]}, ""); + NoteList.finishedLoadingMore();