buddy_list: Include offline users in participants list for large orgs.

This commit is contained in:
evykassirer 2024-09-24 15:55:31 -07:00 committed by Tim Abbott
parent 38e5b4b8fc
commit f5be62f60d
3 changed files with 70 additions and 18 deletions

View File

@ -2,6 +2,7 @@ import assert from "minimalistic-assert";
import * as hash_util from "./hash_util";
import {$t} from "./i18n";
import * as message_lists from "./message_lists";
import * as muted_users from "./muted_users";
import * as narrow_state from "./narrow_state";
import {page_params} from "./page_params";
@ -285,7 +286,11 @@ function user_is_recently_active(user_id: number): boolean {
return level(user_id) <= 2;
}
function maybe_shrink_list(user_ids: number[], user_filter_text: string): number[] {
function maybe_shrink_list(
user_ids: number[],
user_filter_text: string,
conversation_participants: Set<number>,
): number[] {
if (user_ids.length <= max_size_before_shrinking) {
return user_ids;
}
@ -310,7 +315,8 @@ function maybe_shrink_list(user_ids: number[], user_filter_text: string): number
user_ids = user_ids.filter(
(user_id) =>
user_is_recently_active(user_id) ||
user_matches_narrow(user_id, pm_ids_set, filter_by_stream_id ? stream_id : undefined),
user_matches_narrow(user_id, pm_ids_set, filter_by_stream_id ? stream_id : undefined) ||
conversation_participants.has(user_id),
);
return user_ids;
@ -357,8 +363,12 @@ function filter_user_ids(user_filter_text: string, user_ids: number[]): number[]
return [...people.filter_people_by_search_terms(persons, user_filter_text)];
}
function get_filtered_user_id_list(user_filter_text: string): number[] {
let base_user_id_list;
function get_filtered_user_id_list(
user_filter_text: string,
conversation_participants: Set<number>,
): number[] {
// We always want to show conversation participants even if they're inactive.
let base_user_id_list = [...conversation_participants];
if (user_filter_text) {
// If there's a filter, select from all users, not just those
@ -399,10 +409,27 @@ function get_filtered_user_id_list(user_filter_text: string): number[] {
return user_ids;
}
export function get_conversation_participants(): Set<number> {
const participant_ids_set = new Set<number>();
if (!narrow_state.stream_id() || !narrow_state.topic() || !message_lists.current) {
return participant_ids_set;
}
for (const message of message_lists.current.all_messages()) {
if (
!people.is_valid_bot_user(message.sender_id) &&
people.is_person_active(message.sender_id)
) {
participant_ids_set.add(message.sender_id);
}
}
return participant_ids_set;
}
export function get_filtered_and_sorted_user_ids(user_filter_text: string): number[] {
let user_ids;
user_ids = get_filtered_user_id_list(user_filter_text);
user_ids = maybe_shrink_list(user_ids, user_filter_text);
const conversation_participants = get_conversation_participants();
user_ids = get_filtered_user_id_list(user_filter_text, conversation_participants);
user_ids = maybe_shrink_list(user_ids, user_filter_text, conversation_participants);
return sort_users(user_ids);
}

View File

@ -15,7 +15,6 @@ import type {BuddyUserInfo} from "./buddy_data";
import {media_breakpoints_num} from "./css_variables";
import * as hash_util from "./hash_util";
import {$t} from "./i18n";
import * as message_lists from "./message_lists";
import * as message_viewport from "./message_viewport";
import * as narrow_state from "./narrow_state";
import * as padded_widget from "./padded_widget";
@ -90,17 +89,7 @@ function get_render_data(): BuddyListRenderData {
const total_human_users = people.get_active_human_count();
const other_users_count = total_human_users - total_human_subscribers_count;
const hide_headers = should_hide_headers(current_sub, pm_ids_set);
const participant_ids_set = new Set<number>();
if (current_sub && narrow_state.topic() && message_lists.current) {
for (const message of message_lists.current.all_messages()) {
if (
!people.is_valid_bot_user(message.sender_id) &&
people.is_person_active(message.sender_id)
) {
participant_ids_set.add(message.sender_id);
}
}
}
const participant_ids_set = buddy_data.get_conversation_participants();
return {
current_sub,

View File

@ -22,6 +22,8 @@ const presence = zrequire("presence");
const stream_data = zrequire("stream_data");
const user_status = zrequire("user_status");
const buddy_data = zrequire("buddy_data");
const {Filter} = zrequire("filter");
const message_lists = zrequire("message_lists");
// The buddy_data module is mostly tested indirectly through
// activity.test.js, but we should feel free to add direct tests
@ -109,6 +111,7 @@ function test(label, f) {
people.add_active_user(me);
people.initialize_current_user(me.user_id);
muted_users.set_muted_users([]);
message_lists.set_current(undefined);
f(helpers);
@ -376,6 +379,39 @@ test("show offline channel subscribers for small channels", ({override_rewire})
assert.deepEqual(buddy_data.get_filtered_and_sorted_user_ids(""), [me.user_id, alice.user_id]);
});
test("get_conversation_participants", ({override_rewire}) => {
people.add_active_user(selma);
const rome_sub = {name: "Rome", subscribed: true, stream_id: 1001};
stream_data.add_sub(rome_sub);
peer_data.set_subscribers(rome_sub.stream_id, [selma.user_id]);
const filter = new Filter([
{operator: "channel", operand: rome_sub.channel_id},
{operator: "topic", operand: "Foo"},
]);
message_lists.set_current({
data: {
filter,
},
all_messages() {
return [
{
sender_id: selma.user_id,
id: rome_sub.stream_id,
content: "example content",
topic: "Foo",
type: "stream",
},
];
},
});
override_rewire(narrow_state, "stream_id", () => rome_sub.stream_id);
override_rewire(narrow_state, "topic", () => "Foo");
assert.deepEqual(buddy_data.get_conversation_participants(), new Set([selma.user_id]));
});
test("level", () => {
realm.server_presence_offline_threshold_seconds = 200;