]> git.openstreetmap.org Git - rails.git/commitdiff
Add 'after' parameter to history pages
authorAnton Khorev <tony29@yandex.ru>
Sun, 16 Mar 2025 00:18:23 +0000 (03:18 +0300)
committerAnton Khorev <tony29@yandex.ru>
Sun, 16 Mar 2025 16:42:08 +0000 (19:42 +0300)
app/assets/javascripts/index/history.js
app/controllers/changesets_controller.rb
app/views/changesets/index.html.erb
test/controllers/changesets_controller_test.rb
test/system/history_test.rb

index dddd84354473d6a126895b1f738f6261b40cfda5..4264e5dce34c8501518d1c8937588b3d6ddd52ea 100644 (file)
@@ -47,12 +47,24 @@ OSM.History = function (map) {
     $("#sidebar_content .changesets").html(html);
   }
 
-  function displayMoreChangesets(html) {
-    $("#sidebar_content .changeset_more").replaceWith(html);
-    const oldList = $("#sidebar_content .changesets ol").first();
-    const newList = oldList.next("ol");
-    newList.children().appendTo(oldList);
-    newList.remove();
+  function displayMoreChangesets(div, html) {
+    const oldList = $("#sidebar_content .changesets ol");
+
+    div.replaceWith(html);
+
+    const prevNewList = oldList.prevAll("ol");
+    if (prevNewList.length) {
+      prevNewList.next(".changeset_more").remove();
+      prevNewList.children().prependTo(oldList);
+      prevNewList.remove();
+    }
+
+    const nextNewList = oldList.nextAll("ol");
+    if (nextNewList.length) {
+      nextNewList.prev(".changeset_more").remove();
+      nextNewList.children().appendTo(oldList);
+      nextNewList.remove();
+    }
   }
 
   function update() {
@@ -71,6 +83,9 @@ OSM.History = function (map) {
     if (params.has("before")) {
       data.set("before", params.get("before"));
     }
+    if (params.has("after")) {
+      data.set("after", params.get("after"));
+    }
 
     fetch(location.pathname + "?" + data)
       .then(response => response.text())
@@ -90,7 +105,7 @@ OSM.History = function (map) {
     div.find(".loader").show();
 
     $.get($(this).attr("href"), function (html) {
-      displayMoreChangesets(html);
+      displayMoreChangesets(div, html);
       updateMap();
     });
   }
index abdc23f0439b942ff9240eaaff278e5e9fb047d7..5e79f4da62a70ac42bc4e75203c60a70d073de24 100644 (file)
@@ -2,6 +2,7 @@
 
 class ChangesetsController < ApplicationController
   include UserMethods
+  include PaginationMethods
 
   layout "site"
 
@@ -18,11 +19,12 @@ class ChangesetsController < ApplicationController
   # list non-empty changesets in reverse chronological order
   def index
     param! :before, Integer, :min => 1
+    param! :after, Integer, :min => 1
 
-    @params = params.permit(:display_name, :bbox, :friends, :nearby, :before, :list)
+    @params = params.permit(:display_name, :bbox, :friends, :nearby, :before, :after, :list)
 
-    if request.format == :atom && @params[:before]
-      redirect_to url_for(@params.merge(:before => nil)), :status => :moved_permanently
+    if request.format == :atom && (@params[:before] || @params[:after])
+      redirect_to url_for(@params.merge(:before => nil, :after => nil)), :status => :moved_permanently
       return
     end
 
@@ -59,9 +61,7 @@ class ChangesetsController < ApplicationController
         changesets = changesets.where(:user => current_user.nearby)
       end
 
-      changesets = changesets.where(:changesets => { :id => ...@params[:before] }) if @params[:before]
-
-      @changesets = changesets.order("changesets.id DESC").limit(20).preload(:user, :changeset_tags, :comments)
+      @changesets, @newer_changesets_id, @older_changesets_id = get_page_items(changesets, :includes => [:user, :changeset_tags, :comments])
 
       render :action => :index, :layout => false
     end
index 85c5f0bcb08a94e2e267fbc6fb8aa6dd82523713..3f25cf134bfbf7bce96fe25afd0c2bb1d599d59d 100644 (file)
@@ -1,17 +1,17 @@
-<% if @changesets.present? %>
-  <ol class="changesets list-group list-group-flush">
-    <%= render @changesets %>
-  </ol>
-<% if @changesets.size == 20 -%>
-  <div class="changeset_more mt-3 text-center">
-    <%= link_to t(".load_more"), url_for(@params.merge(:before => @changesets.last.id)), :class => "btn btn-primary" %>
+<% if @newer_changesets_id %>
+  <div class="changeset_more my-3 text-center">
+    <%= link_to t(".load_more"), url_for(@params.merge(:before => nil, :after => @newer_changesets_id)), :class => "btn btn-primary" %>
     <div class="text-center loader">
       <div class="spinner-border" role="status">
         <span class="visually-hidden"><%= t("browse.start_rjs.loading") %></span>
       </div>
     </div>
   </div>
-<% end -%>
+<% end %>
+<% if @changesets.present? %>
+  <ol class="changesets list-group list-group-flush">
+    <%= render @changesets %>
+  </ol>
 <% elsif params[:bbox] %>
   <p class="mx-3"><%= params[:before] ? t(".no_more_area") : t(".empty_area") %></p>
 <% elsif params[:display_name] %>
 <% else %>
   <p class="mx-3"><%= params[:before] ? t(".no_more") : t(".empty") %></p>
 <% end %>
+<% if @older_changesets_id -%>
+  <div class="changeset_more my-3 text-center">
+    <%= link_to t(".load_more"), url_for(@params.merge(:before => @older_changesets_id, :after => nil)), :class => "btn btn-primary" %>
+    <div class="text-center loader">
+      <div class="spinner-border" role="status">
+        <span class="visually-hidden"><%= t("browse.start_rjs.loading") %></span>
+      </div>
+    </div>
+  </div>
+<% end -%>
index 4274f7c313cc7856a6dceaae7a5a7c19babefea7..452084951105492536e344cf21e6247aeacc2f24 100644 (file)
@@ -82,6 +82,9 @@ class ChangesetsControllerTest < ActionDispatch::IntegrationTest
     %w[-1 0 fred].each do |id|
       get history_path(:format => "html", :list => "1", :before => id)
       assert_redirected_to :controller => :errors, :action => :bad_request
+
+      get history_path(:format => "html", :list => "1", :after => id)
+      assert_redirected_to :controller => :errors, :action => :bad_request
     end
   end
 
@@ -238,6 +241,23 @@ class ChangesetsControllerTest < ActionDispatch::IntegrationTest
     check_index_result [changeset1]
   end
 
+  def test_index_after_id
+    changeset1 = create(:changeset, :num_changes => 1)
+    changeset2 = create(:changeset, :num_changes => 1)
+
+    get history_path(:format => "html", :after => changeset1.id), :xhr => true
+    assert_response :success
+    assert_template "history"
+    assert_template :layout => "xhr"
+    assert_select "h2", :text => "Changesets", :count => 1
+
+    get history_path(:format => "html", :list => "1", :after => changeset1.id), :xhr => true
+    assert_response :success
+    assert_template "index"
+
+    check_index_result [changeset2]
+  end
+
   ##
   # Check that a list with a next page link works
   def test_index_more
@@ -416,6 +436,11 @@ class ChangesetsControllerTest < ActionDispatch::IntegrationTest
     assert_redirected_to :action => :feed
   end
 
+  def test_feed_after
+    get history_feed_path(:format => "atom", :after => 100)
+    assert_redirected_to :action => :feed
+  end
+
   private
 
   ##
index 4f2114f25dbc1669bc11642d86e75cf737a77b5b..7d730355a083c9b327cd6452b3dd4aca96f216e8 100644 (file)
@@ -81,6 +81,34 @@ class HistoryTest < ApplicationSystemTestCase
     end
   end
 
+  test "user history starts after specified changeset" do
+    user = create(:user)
+    changeset0 = create(:changeset)
+    changeset1 = create_visible_changeset(user, "1st-changeset-in-history")
+    changeset2 = create_visible_changeset(user, "2nd-changeset-in-history")
+
+    visit "#{user_path user}/history?after=#{changeset2.id}"
+
+    within_sidebar do
+      assert_no_link "1st-changeset-in-history"
+      assert_no_link "2nd-changeset-in-history"
+    end
+
+    visit "#{user_path user}/history?after=#{changeset1.id}"
+
+    within_sidebar do
+      assert_no_link "1st-changeset-in-history"
+      assert_link "2nd-changeset-in-history"
+    end
+
+    visit "#{user_path user}/history?after=#{changeset0.id}"
+
+    within_sidebar do
+      assert_link "1st-changeset-in-history"
+      assert_link "2nd-changeset-in-history"
+    end
+  end
+
   private
 
   def create_visible_changeset(user, comment)