FIX: sort chat channels by mentions, unread and channel title (#25565)
This change will sort channels by activity on mobile, with preference to those with urgent or unread messages. Channels with mentions will appear first, followed by channels with unread messages, then finally everything else sorted by the channel title (alphabetically).
This commit is contained in:
parent
1403217ca4
commit
aac28b9048
|
@ -19,6 +19,7 @@ export default class ChatChannelsManager extends Service {
|
|||
@service chatApi;
|
||||
@service currentUser;
|
||||
@service router;
|
||||
@service site;
|
||||
@tracked _cached = new TrackedObject();
|
||||
|
||||
async find(id, options = { fetchIfNotFound: true }) {
|
||||
|
@ -111,12 +112,16 @@ export default class ChatChannelsManager extends Service {
|
|||
|
||||
@cached
|
||||
get publicMessageChannels() {
|
||||
return this.channels
|
||||
.filter(
|
||||
(channel) =>
|
||||
channel.isCategoryChannel && channel.currentUserMembership.following
|
||||
)
|
||||
.sort((a, b) => a?.slug?.localeCompare?.(b?.slug));
|
||||
const channels = this.channels.filter(
|
||||
(channel) =>
|
||||
channel.isCategoryChannel && channel.currentUserMembership.following
|
||||
);
|
||||
|
||||
if (this.site.mobileView) {
|
||||
return this.#sortChannelsByActivity(channels);
|
||||
} else {
|
||||
return channels.sort((a, b) => a?.title?.localeCompare?.(b?.title));
|
||||
}
|
||||
}
|
||||
|
||||
@cached
|
||||
|
@ -154,6 +159,32 @@ export default class ChatChannelsManager extends Service {
|
|||
return this._cached[id];
|
||||
}
|
||||
|
||||
#sortChannelsByActivity(channels) {
|
||||
return channels.sort((a, b) => {
|
||||
// if both channels have mention count, sort by aplhabetical order
|
||||
// otherwise prioritize channel with mention count
|
||||
if (a.tracking.mentionCount > 0 && b.tracking.mentionCount > 0) {
|
||||
return a.title?.localeCompare?.(b.title);
|
||||
}
|
||||
|
||||
if (a.tracking.mentionCount > 0 || b.tracking.mentionCount > 0) {
|
||||
return a.tracking.mentionCount > b.tracking.mentionCount ? -1 : 1;
|
||||
}
|
||||
|
||||
// if both channels have unread count, sort by aplhabetical order
|
||||
// otherwise prioritize channel with unread count
|
||||
if (a.tracking.unreadCount > 0 && b.tracking.unreadCount > 0) {
|
||||
return a.title?.localeCompare?.(b.title);
|
||||
}
|
||||
|
||||
if (a.tracking.unreadCount > 0 || b.tracking.unreadCount > 0) {
|
||||
return a.tracking.unreadCount > b.tracking.unreadCount ? -1 : 1;
|
||||
}
|
||||
|
||||
return a.title?.localeCompare?.(b.title);
|
||||
});
|
||||
}
|
||||
|
||||
#sortDirectMessageChannels(channels) {
|
||||
return channels.sort((a, b) => {
|
||||
if (!a.lastMessage.id) {
|
||||
|
|
|
@ -50,24 +50,55 @@ RSpec.describe "List channels | mobile", type: :system, mobile: true do
|
|||
end
|
||||
|
||||
context "when multiple category channels are present" do
|
||||
fab!(:channel_1) { Fabricate(:category_channel, name: "b channel") }
|
||||
fab!(:channel_2) { Fabricate(:category_channel, name: "a channel") }
|
||||
fab!(:channel_1) { Fabricate(:category_channel, name: "a channel") }
|
||||
fab!(:channel_2) { Fabricate(:category_channel, name: "b channel") }
|
||||
fab!(:channel_3) { Fabricate(:category_channel, name: "c channel") }
|
||||
fab!(:channel_4) { Fabricate(:category_channel, name: "d channel") }
|
||||
|
||||
before do
|
||||
channel_1.add(current_user)
|
||||
channel_2.add(current_user)
|
||||
channel_3.add(current_user)
|
||||
channel_4.add(current_user)
|
||||
end
|
||||
|
||||
it "sorts them alphabetically" do
|
||||
visit("/chat")
|
||||
page.find("#c-footer-channels").click
|
||||
it "sorts them by mentions, unread, then alphabetical order" do
|
||||
Jobs.run_immediately!
|
||||
|
||||
expect(page.find("#public-channels a:nth-child(1)")["data-chat-channel-id"]).to eq(
|
||||
channel_2.id.to_s,
|
||||
Fabricate(
|
||||
:chat_message,
|
||||
chat_channel: channel_1,
|
||||
created_at: 10.minutes.ago,
|
||||
use_service: true,
|
||||
)
|
||||
Fabricate(
|
||||
:chat_message,
|
||||
chat_channel: channel_2,
|
||||
created_at: 5.minutes.ago,
|
||||
use_service: true,
|
||||
)
|
||||
Fabricate(
|
||||
:chat_message_with_service,
|
||||
chat_channel: channel_4,
|
||||
message: "Hey @#{current_user.username}",
|
||||
user: Fabricate(:user),
|
||||
)
|
||||
|
||||
Fabricate(:chat_message, chat_channel: channel_3, user: current_user, use_service: true)
|
||||
|
||||
visit("/chat/channels")
|
||||
|
||||
# channel with mentions should be first
|
||||
expect(page.find("#public-channels a:nth-child(1)")["data-chat-channel-id"]).to eq(
|
||||
channel_4.id.to_s,
|
||||
)
|
||||
# channels with unread messages are next, sorted by title
|
||||
expect(page.find("#public-channels a:nth-child(2)")["data-chat-channel-id"]).to eq(
|
||||
channel_1.id.to_s,
|
||||
)
|
||||
expect(page.find("#public-channels a:nth-child(3)")["data-chat-channel-id"]).to eq(
|
||||
channel_2.id.to_s,
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
Loading…
Reference in New Issue