invite: Fetch full user set for get_unique_subscriber_count_for_streams.

Work towards #34244.
This commit is contained in:
Evy Kassirer
2025-05-08 11:32:48 +02:00
committed by Tim Abbott
parent 3e9d3a8ff4
commit 25c0b279f7
6 changed files with 43 additions and 14 deletions

View File

@@ -5,7 +5,6 @@ import assert from "minimalistic-assert";
import {z} from "zod";
import render_copy_invite_link from "../templates/copy_invite_link.hbs";
import render_guest_visible_users_message from "../templates/guest_visible_users_message.hbs";
import render_invitation_failed_error from "../templates/invitation_failed_error.hbs";
import render_invite_user_modal from "../templates/invite_user_modal.hbs";
import render_invite_tips_banner from "../templates/modal_banner/invite_tips_banner.hbs";
@@ -21,6 +20,7 @@ import * as dialog_widget from "./dialog_widget.ts";
import * as email_pill from "./email_pill.ts";
import {$t, $t_html} from "./i18n.ts";
import * as invite_stream_picker_pill from "./invite_stream_picker_pill.ts";
import * as loading from "./loading.ts";
import {page_params} from "./page_params.ts";
import * as peer_data from "./peer_data.ts";
import * as settings_components from "./settings_components.ts";
@@ -301,7 +301,7 @@ function set_streams_to_join_list_visibility(): void {
}
}
function update_guest_visible_users_count_and_stream_ids(): void {
async function update_guest_visible_users_count_and_stream_ids(): Promise<void> {
const invite_as = Number.parseInt(
$<HTMLSelectOneElement>("select:not([multiple])#invite_as").val()!,
10,
@@ -320,13 +320,14 @@ function update_guest_visible_users_count_and_stream_ids(): void {
const stream_ids = $("#invite_select_default_streams").is(":checked")
? stream_data.get_default_stream_ids()
: stream_pill.get_stream_ids(stream_pill_widget);
const visible_users_count = peer_data.get_unique_subscriber_count_for_streams(stream_ids);
const message_html = render_guest_visible_users_message({
user_count: visible_users_count,
});
$(".guest-visible-users-count").empty();
loading.make_indicator($(".guest_visible_users_loading"));
$("#guest_visible_users_container").show();
$("#guest_visible_users_container").html(message_html).show();
const visible_users_count = await peer_data.get_unique_subscriber_count_for_streams(stream_ids);
$(".guest-visible-users-count").text(visible_users_count);
loading.destroy_indicator($(".guest_visible_users_loading"));
}
function generate_invite_tips_data(): Record<string, boolean> {
@@ -415,12 +416,12 @@ function open_invite_user_modal(e: JQuery.ClickEvent<Document, undefined>): void
$("#invite_streams_container .input, #invite_select_default_streams").on(
"change",
update_guest_visible_users_count_and_stream_ids,
() => void update_guest_visible_users_count_and_stream_ids(),
);
$("#invite_as").on("change", () => {
update_stream_list();
update_guest_visible_users_count_and_stream_ids();
void update_guest_visible_users_count_and_stream_ids();
});
$("#invite-user-modal").on("click", ".setup-tips-container .banner_content a", () => {

View File

@@ -112,6 +112,11 @@ function get_loaded_subscriber_subset(stream_id: number): LazySet {
return subscribers;
}
async function get_full_subscriber_set(stream_id: number, retry_on_failure: true): Promise<LazySet>;
async function get_full_subscriber_set(
stream_id: number,
retry_on_failure: boolean,
): Promise<LazySet | null>;
async function get_full_subscriber_set(
stream_id: number,
retry_on_failure: boolean,
@@ -317,11 +322,19 @@ export async function maybe_fetch_is_user_subscribed(
return subscribers.has(user_id);
}
export function get_unique_subscriber_count_for_streams(stream_ids: number[]): number {
export async function get_unique_subscriber_count_for_streams(
stream_ids: number[],
): Promise<number> {
const valid_subscribers = new LazySet([]);
const promises: Record<number, Promise<LazySet>> = {};
for (const stream_id of stream_ids) {
promises[stream_id] = get_full_subscriber_set(stream_id, true);
}
for (const stream_id of stream_ids) {
const subscribers = get_loaded_subscriber_subset(stream_id);
// If it's `null`, that means a request failed and we don't know the
// full subscribers set, so just use whatever we have already.
const subscribers = await promises[stream_id]!;
for (const user_id of subscribers.keys()) {
if (!people.is_valid_bot_user(user_id)) {

View File

@@ -1326,6 +1326,14 @@ div.toggle_resolve_topic_spinner .loading_indicator_spinner {
vertical-align: bottom;
}
#invite-user-form .loading_indicator_spinner {
height: 1em;
width: fit-content;
display: inline-block;
float: none;
margin: 0 5px;
}
.add-user-group-container,
.add_streams_container {
display: inline-flex;

View File

@@ -1,4 +1,10 @@
<p id="guest_visible_users_message">
{{t 'Guests will be able to see {user_count} users in their channels when they join.'}}
{{#tr}}
Guests will be able to see <z-user-count></z-user-count> users in their channels when they join.
{{#*inline "z-user-count"}}
<span class="guest-visible-users-count" aria-hidden="true"></span>
<span class="guest_visible_users_loading"></span>
{{/inline}}
{{/tr}}
{{> help_link_widget link="/help/guest-users#configure-whether-guests-can-see-all-other-users" }}
</p>

View File

@@ -85,6 +85,7 @@
</div>
</div>
<div id="guest_visible_users_container" class="input-group" style="display: none;">
{{> guest_visible_users_message}}
</div>
{{#if show_group_pill_container}}
<div class="input-group">

View File

@@ -447,7 +447,7 @@ test("is_subscriber_subset", async () => {
assert.equal(await peer_data.is_subscriber_subset(sub_a.stream_id, sub_b.stream_id), null);
});
test("get_unique_subscriber_count_for_streams", () => {
test("get_unique_subscriber_count_for_streams", async () => {
const sub = {name: "Rome", subscribed: true, stream_id: 1001};
stream_data.add_sub(sub);
@@ -459,7 +459,7 @@ test("get_unique_subscriber_count_for_streams", () => {
const stream_id = sub.stream_id;
peer_data.set_subscribers(stream_id, [me.user_id, fred.user_id, bot_botson.user_id]);
const count = peer_data.get_unique_subscriber_count_for_streams([stream_id]);
const count = await peer_data.get_unique_subscriber_count_for_streams([stream_id]);
assert.equal(count, 2);
});