diff --git a/app/controllers/users/sidebars_controller.rb b/app/controllers/users/sidebars_controller.rb index ce998e8..4943a34 100644 --- a/app/controllers/users/sidebars_controller.rb +++ b/app/controllers/users/sidebars_controller.rb @@ -2,8 +2,9 @@ class Users::SidebarsController < ApplicationController DIRECT_PLACEHOLDERS = 20 def show - @direct_memberships, @other_memberships = Current.user.memberships.visible.with_ordered_room.partition { |membership| membership.room.direct? } - @direct_memberships = @direct_memberships.sort_by { |membership| membership.room.updated_at }.reverse + visible_memberships = Current.user.memberships.visible + @direct_memberships = visible_memberships.with_direct_rooms + @other_memberships = visible_memberships.without_direct_rooms.with_ordered_room @direct_placeholder_users = find_direct_placeholder_users end diff --git a/app/models/membership.rb b/app/models/membership.rb index 74c225b..da7a0a6 100644 --- a/app/models/membership.rb +++ b/app/models/membership.rb @@ -9,6 +9,7 @@ class Membership < ApplicationRecord enum :involvement, %w[ invisible nothing mentions everything ].index_by(&:itself), prefix: :involved_in scope :with_ordered_room, -> { includes(:room).joins(:room).order("LOWER(rooms.name)") } + scope :with_direct_rooms, -> { includes(:room).joins(:room).where(rooms: { type: "Rooms::Direct" }).order(rooms: { updated_at: :desc }) } scope :without_direct_rooms, -> { joins(:room).where.not(room: { type: "Rooms::Direct" }) } scope :visible, -> { where.not(involvement: :invisible) } diff --git a/test/controllers/users/sidebars_controller_test.rb b/test/controllers/users/sidebars_controller_test.rb index 50caae7..5ed957a 100644 --- a/test/controllers/users/sidebars_controller_test.rb +++ b/test/controllers/users/sidebars_controller_test.rb @@ -27,4 +27,25 @@ class Users::SidebarsControllerTest < ActionDispatch::IntegrationTest get user_sidebar_url assert_select ".unread", count: users(:david).memberships.reject { |m| m.room.direct? || !m.unread? }.count end + + test "directs are queried separately and ordered by room recency, not name" do + older = rooms(:david_and_jason) + newer = rooms(:david_and_kevin) + older.update_column :updated_at, 2.days.ago + newer.update_column :updated_at, 1.minute.ago + + get user_sidebar_url + + assert_operator @response.body.index(dom_id(newer, :list)), :<, @response.body.index(dom_id(older, :list)) + end + + test "shared rooms stay ordered by name" do + get user_sidebar_url + + shared_ids = users(:david).rooms.without_directs.sort_by { |room| room.name.downcase }.map { |room| dom_id(room, :list) } + positions = shared_ids.map { |id| @response.body.index(id) } + + assert positions.all? + assert_equal positions.sort, positions + end end