Commit e802d00996d6948e29f085d4de9409423e0d91a4

Authored by Riyad Preukschas
1 parent 14164017

Completely redo loading of notes with JS

app/assets/javascripts/note.js
@@ -4,9 +4,8 @@ var NoteList = { @@ -4,9 +4,8 @@ var NoteList = {
4 target_params: null, 4 target_params: null,
5 target_id: 0, 5 target_id: 0,
6 target_type: null, 6 target_type: null,
7 - first_id: 0,  
8 - last_id: 0,  
9 - disable:false, 7 + bottom_id: 0,
  8 + loading_more_disabled: false,
10 9
11 init: 10 init:
12 function(tid, tt, path) { 11 function(tid, tt, path) {
@@ -15,26 +14,23 @@ var NoteList = { @@ -15,26 +14,23 @@ var NoteList = {
15 this.target_type = tt; 14 this.target_type = tt;
16 this.target_params = "&target_type=" + this.target_type + "&target_id=" + this.target_id; 15 this.target_params = "&target_type=" + this.target_type + "&target_id=" + this.target_id;
17 16
18 - // get notes 17 + // get initial set of notes
19 this.getContent(); 18 this.getContent();
20 19
21 - // get new notes every n seconds  
22 - this.initRefresh();  
23 -  
24 $('.delete-note').live('ajax:success', function() { 20 $('.delete-note').live('ajax:success', function() {
25 $(this).closest('li').fadeOut(); }); 21 $(this).closest('li').fadeOut(); });
26 22
27 - $(".note-form-holder").live("ajax:before", function(){ 23 + $(".note-form-holder").on("ajax:before", function(){
28 $(".submit_note").disable() 24 $(".submit_note").disable()
29 }) 25 })
30 26
31 - $(".note-form-holder").live("ajax:complete", function(){ 27 + $(".note-form-holder").on("ajax:complete", function(){
32 $(".submit_note").enable() 28 $(".submit_note").enable()
33 }) 29 })
34 30
35 disableButtonIfEmptyField(".note-text", ".submit_note"); 31 disableButtonIfEmptyField(".note-text", ".submit_note");
36 32
37 - $(".note-text").live("focus", function(){ 33 + $(".note-text").on("focus", function(){
38 $(this).css("height", "80px"); 34 $(this).css("height", "80px");
39 $('.note_advanced_opts').show(); 35 $('.note_advanced_opts').show();
40 }); 36 });
@@ -44,64 +40,20 @@ var NoteList = { @@ -44,64 +40,20 @@ var NoteList = {
44 var filename = val.replace(/^.*[\\\/]/, ''); 40 var filename = val.replace(/^.*[\\\/]/, '');
45 $(".file_name").text(filename); 41 $(".file_name").text(filename);
46 }); 42 });
47 -  
48 }, 43 },
49 44
50 45
51 /** 46 /**
52 - * Load new notes to fresh list called 'new_notes_list':  
53 - * - Replace 'new_notes_list' with new list every n seconds  
54 - * - Append new notes to this list after submit 47 + * Handle loading the initial set of notes.
  48 + * And set up loading more notes when scrolling to the bottom of the page.
55 */ 49 */
56 50
57 - initRefresh:  
58 - function() {  
59 - // init timer  
60 - var intNew = setInterval("NoteList.getNew()", 10000);  
61 - },  
62 -  
63 - replace:  
64 - function(html) {  
65 - $("#new_notes_list").html(html);  
66 - },  
67 -  
68 - prepend:  
69 - function(id, html) {  
70 - if(id != this.last_id) {  
71 - $("#new_notes_list").prepend(html);  
72 - }  
73 - },  
74 -  
75 - getNew:  
76 - function() {  
77 - // refersh notes list  
78 - $.ajax({  
79 - type: "GET",  
80 - url: this.notes_path,  
81 - data: "last_id=" + this.last_id + this.target_params,  
82 - dataType: "script"});  
83 - },  
84 -  
85 - refresh:  
86 - function() {  
87 - // refersh notes list  
88 - $.ajax({  
89 - type: "GET",  
90 - url: this.notes_path,  
91 - data: "first_id=" + this.first_id + "&last_id=" + this.last_id + this.target_params,  
92 - dataType: "script"});  
93 - },  
94 -  
95 51
96 /** 52 /**
97 - * Init load of notes:  
98 - * 1. Get content with ajax call  
99 - * 2. Set content of notes list with loaded one 53 + * Gets an inital set of notes.
100 */ 54 */
101 -  
102 -  
103 - getContent:  
104 - function() { 55 + getContent:
  56 + function() {
105 $.ajax({ 57 $.ajax({
106 type: "GET", 58 type: "GET",
107 url: this.notes_path, 59 url: this.notes_path,
@@ -111,10 +63,13 @@ var NoteList = { @@ -111,10 +63,13 @@ var NoteList = {
111 dataType: "script"}); 63 dataType: "script"});
112 }, 64 },
113 65
  66 + /**
  67 + * Called in response to getContent().
  68 + * Replaces the content of #notes-list with the given html.
  69 + */
114 setContent: 70 setContent:
115 - function(fid, lid, html) {  
116 - this.last_id = lid;  
117 - this.first_id = fid; 71 + function(last_id, html) {
  72 + this.bottom_id = last_id;
118 $("#notes-list").html(html); 73 $("#notes-list").html(html);
119 74
120 // Init infinite scrolling 75 // Init infinite scrolling
@@ -123,54 +78,126 @@ var NoteList = { @@ -123,54 +78,126 @@ var NoteList = {
123 78
124 79
125 /** 80 /**
126 - * Paging for old notes when scroll to bottom:  
127 - * 1. Init scroll events with 'initLoadMore'  
128 - * 2. Load onlder notes with 'getOld' method  
129 - * 3. append old notes to bottom of list with 'append' 81 + * Handle loading more notes when scrolling to the bottom of the page.
  82 + * The id of the last note in the list is in this.bottom_id.
130 * 83 *
  84 + * Set up refreshing only new notes after all notes have been loaded.
131 */ 85 */
132 - getOld: 86 +
  87 +
  88 + /**
  89 + * Initializes loading more notes when scrolling to the bottom of the page.
  90 + */
  91 + initLoadMore:
133 function() { 92 function() {
  93 + $(document).endlessScroll({
  94 + bottomPixels: 400,
  95 + fireDelay: 1000,
  96 + fireOnce:true,
  97 + ceaseFire: function() {
  98 + return NoteList.loading_more_disabled;
  99 + },
  100 + callback: function(i) {
  101 + NoteList.getMore();
  102 + }
  103 + });
  104 + },
  105 +
  106 + /**
  107 + * Gets an additional set of notes.
  108 + */
  109 + getMore:
  110 + function() {
  111 + // only load more notes if there are no "new" notes
134 $('.loading').show(); 112 $('.loading').show();
135 $.ajax({ 113 $.ajax({
136 type: "GET", 114 type: "GET",
137 url: this.notes_path, 115 url: this.notes_path,
138 - data: "first_id=" + this.first_id + this.target_params, 116 + data: "loading_more=1&after_id=" + this.bottom_id + this.target_params,
139 complete: function(){ $('.notes-status').removeClass("loading")}, 117 complete: function(){ $('.notes-status').removeClass("loading")},
140 beforeSend: function() { $('.notes-status').addClass("loading") }, 118 beforeSend: function() { $('.notes-status').addClass("loading") },
141 dataType: "script"}); 119 dataType: "script"});
142 }, 120 },
143 121
144 - append: 122 + /**
  123 + * Called in response to getMore().
  124 + * Append notes to #notes-list.
  125 + */
  126 + appendMoreNotes:
145 function(id, html) { 127 function(id, html) {
146 - if(this.first_id == id) {  
147 - this.disable = true;  
148 - } else {  
149 - this.first_id = id; 128 + if(id != this.bottom_id) {
  129 + this.bottom_id = id;
150 $("#notes-list").append(html); 130 $("#notes-list").append(html);
151 } 131 }
152 }, 132 },
153 133
154 - initLoadMore: 134 + /**
  135 + * Called in response to getMore().
  136 + * Disables loading more notes when scrolling to the bottom of the page.
  137 + * Initalizes refreshing new notes.
  138 + */
  139 + finishedLoadingMore:
155 function() { 140 function() {
156 - $(document).endlessScroll({  
157 - bottomPixels: 400,  
158 - fireDelay: 1000,  
159 - fireOnce:true,  
160 - ceaseFire: function() {  
161 - return NoteList.disable;  
162 - },  
163 - callback: function(i) {  
164 - NoteList.getOld(); 141 + this.loading_more_disabled = true;
  142 +
  143 + // from now on only get new notes
  144 + this.initRefreshNew();
  145 + },
  146 +
  147 +
  148 + /**
  149 + * Handle refreshing and adding of new notes.
  150 + *
  151 + * New notes are all notes that are created after the site has been loaded.
  152 + * The "old" notes are in #notes-list the "new" ones will be in #new-notes-list.
  153 + * The id of the last "old" note is in this.bottom_id.
  154 + */
  155 +
  156 +
  157 + /**
  158 + * Initializes getting new notes every n seconds.
  159 + */
  160 + initRefreshNew:
  161 + function() {
  162 + setInterval("NoteList.getNew()", 10000);
  163 + },
  164 +
  165 + /**
  166 + * Gets the new set of notes (i.e. all notes after ).
  167 + */
  168 + getNew:
  169 + function() {
  170 + $.ajax({
  171 + type: "GET",
  172 + url: this.notes_path,
  173 + data: "loading_new=1&after_id=" + this.bottom_id + this.target_params,
  174 + dataType: "script"});
  175 + },
  176 +
  177 + /**
  178 + * Called in response to getNew().
  179 + * Replaces the content of #new-notes-list with the given html.
  180 + */
  181 + replaceNewNotes:
  182 + function(html) {
  183 + $("#new-notes-list").html(html);
  184 + },
  185 +
  186 + /**
  187 + * Adds a single note to #new-notes-list.
  188 + */
  189 + appendNewNote:
  190 + function(id, html) {
  191 + if(id != this.bottom_id) {
  192 + $("#new-notes-list").append(html);
165 } 193 }
166 - });  
167 } 194 }
168 }; 195 };
169 196
170 -var PerLineNotes = { 197 +var PerLineNotes = {
171 init: 198 init:
172 function() { 199 function() {
173 - $(".line_note_link, .line_note_reply_link").live("click", function(e) { 200 + $(".line_note_link, .line_note_reply_link").on("click", function(e) {
174 var form = $(".per_line_form"); 201 var form = $(".per_line_form");
175 $(this).closest("tr").after(form); 202 $(this).closest("tr").after(form);
176 form.find("#note_line_code").val($(this).attr("line_code")); 203 form.find("#note_line_code").val($(this).attr("line_code"));
app/contexts/notes/load_context.rb
@@ -3,8 +3,7 @@ module Notes @@ -3,8 +3,7 @@ module Notes
3 def execute 3 def execute
4 target_type = params[:target_type] 4 target_type = params[:target_type]
5 target_id = params[:target_id] 5 target_id = params[:target_id]
6 - first_id = params[:first_id]  
7 - last_id = params[:last_id] 6 + after_id = params[:after_id]
8 7
9 8
10 @notes = case target_type 9 @notes = case target_type
@@ -23,10 +22,8 @@ module Notes @@ -23,10 +22,8 @@ module Notes
23 project.wikis.reverse.map {|w| w.notes.fresh }.flatten[0..20] 22 project.wikis.reverse.map {|w| w.notes.fresh }.flatten[0..20]
24 end 23 end
25 24
26 - @notes = if last_id  
27 - @notes.where("id < ?", last_id)  
28 - elsif first_id  
29 - @notes.where("id > ?", first_id) 25 + @notes = if after_id
  26 + @notes.where("id > ?", after_id)
30 else 27 else
31 @notes 28 @notes
32 end 29 end
app/helpers/notes_helper.rb 0 → 100644
@@ -0,0 +1,9 @@ @@ -0,0 +1,9 @@
  1 +module NotesHelper
  2 + def loading_more_notes?
  3 + params[:loading_more].present?
  4 + end
  5 +
  6 + def loading_new_notes?
  7 + params[:loading_new].present?
  8 + end
  9 +end
app/views/notes/_create_common.js.haml
@@ -5,7 +5,8 @@ @@ -5,7 +5,8 @@
5 $('.note-form-holder #preview-link').text('Preview'); 5 $('.note-form-holder #preview-link').text('Preview');
6 $('.note-form-holder #preview-note').hide(); 6 $('.note-form-holder #preview-note').hide();
7 $('.note-form-holder').show(); 7 $('.note-form-holder').show();
8 - NoteList.prepend(#{note.id}, "#{escape_javascript(render partial: "notes/show", locals: {note: note})}"); 8 + NoteList.appendNewNote(#{note.id}, "#{escape_javascript(render "notes/show", note: note)}");
  9 +
9 - else 10 - else
10 :plain 11 :plain
11 $(".note-form-holder").replaceWith("#{escape_javascript(render('form'))}"); 12 $(".note-form-holder").replaceWith("#{escape_javascript(render('form'))}");
app/views/notes/_load.js.haml
1 - unless @notes.blank? 1 - unless @notes.blank?
2 - - if params[:last_id] 2 + - if loading_more_notes?
3 :plain 3 :plain
4 - NoteList.replace("#{escape_javascript(render(partial: 'notes/notes_list'))}"); 4 + NoteList.appendMoreNotes(#{@notes.last.id}, "#{escape_javascript(render 'notes/notes_list')}");
5 5
6 - - elsif params[:first_id] 6 + - elsif loading_new_notes?
7 :plain 7 :plain
8 - NoteList.append(#{@notes.last.id}, "#{escape_javascript(render(partial: 'notes/notes_list'))}"); 8 + NoteList.replaceNewNotes("#{escape_javascript(render 'notes/notes_list')}");
9 9
10 - else 10 - else
11 :plain 11 :plain
12 - NoteList.setContent(#{@notes.last.id}, #{@notes.first.id}, "#{escape_javascript(render(partial: 'notes/notes_list'))}"); 12 + NoteList.setContent(#{@notes.last.id}, "#{escape_javascript(render 'notes/notes_list')}");
13 13
14 - else 14 - else
15 - - if params[:first_id] 15 + - if loading_more_notes?
16 :plain 16 :plain
17 - NoteList.append(#{params[:first_id]}, ""); 17 + NoteList.finishedLoadingMore();