diff --git a/web/src/activity_ui.ts b/web/src/activity_ui.ts
index dad62269cf..a29e48d5b3 100644
--- a/web/src/activity_ui.ts
+++ b/web/src/activity_ui.ts
@@ -59,6 +59,17 @@ export function clear_for_testing(): void {
user_filter = undefined;
}
+export function update_presence_indicators(): void {
+ $("[data-presence-indicator-user-id]").each(function () {
+ const user_id = Number.parseInt($(this).attr("data-presence-indicator-user-id") ?? "", 10);
+ assert(!Number.isNaN(user_id));
+ const user_circle_class = buddy_data.get_user_circle_class(user_id);
+ $(this)
+ .removeClass("user_circle_empty user_circle_green user_circle_idle")
+ .addClass(user_circle_class);
+ });
+}
+
export function redraw_user(user_id: number): void {
if (realm.realm_presence_disabled) {
return;
@@ -76,6 +87,7 @@ export function redraw_user(user_id: number): void {
user_id,
item: info,
});
+ update_presence_indicators();
}
export function check_should_redraw_new_user(user_id: number): boolean {
@@ -178,6 +190,7 @@ export function redraw(): void {
assert(user_cursor !== undefined);
user_cursor.redraw();
pm_list.update_private_messages();
+ update_presence_indicators();
}
export function reset_users(): void {
diff --git a/web/templates/inbox_view/inbox_row.hbs b/web/templates/inbox_view/inbox_row.hbs
index d32dfe42f9..2b4e323a5e 100644
--- a/web/templates/inbox_view/inbox_row.hbs
+++ b/web/templates/inbox_view/inbox_row.hbs
@@ -14,7 +14,7 @@
{{else if is_group}}
{{else}}
-
+
{{/if}}
{{{rendered_dm_with}}}
diff --git a/web/templates/popovers/user_card/user_card_popover.hbs b/web/templates/popovers/user_card/user_card_popover.hbs
index 86249ebd6b..c6487f4a01 100644
--- a/web/templates/popovers/user_card/user_card_popover.hbs
+++ b/web/templates/popovers/user_card/user_card_popover.hbs
@@ -8,7 +8,8 @@
{{#if is_bot}}
{{else}}
-
+
{{/if}}
{{/if}}
{{#if show_manage_menu }}
diff --git a/web/templates/recent_view_row.hbs b/web/templates/recent_view_row.hbs
index 10cfae3644..10758d9848 100644
--- a/web/templates/recent_view_row.hbs
+++ b/web/templates/recent_view_row.hbs
@@ -21,7 +21,7 @@
{{else if is_bot}}
{{else}}
-
+
{{/if}}
diff --git a/web/templates/user_profile_modal.hbs b/web/templates/user_profile_modal.hbs
index d3c9a91500..9618f57954 100644
--- a/web/templates/user_profile_modal.hbs
+++ b/web/templates/user_profile_modal.hbs
@@ -6,7 +6,7 @@
{{#unless is_bot}}
{{#if is_active}}
-
+
{{else}}
diff --git a/web/tests/activity.test.js b/web/tests/activity.test.js
index 89e47488f6..3275a07c5b 100644
--- a/web/tests/activity.test.js
+++ b/web/tests/activity.test.js
@@ -537,6 +537,22 @@ test("insert_one_user_into_empty_list", ({override, mock_template}) => {
$other_users_appended = $element;
});
+ $.create("[data-presence-indicator-user-id]", {
+ children: [
+ {
+ to_$() {
+ return {
+ attr: () => 1,
+ removeClass() {
+ return this;
+ },
+ addClass: noop,
+ };
+ },
+ },
+ ],
+ });
+
add_sub_and_set_as_current_narrow(rome_sub);
buddy_list_add_user_matching_view(alice.user_id, $alice_stub);
@@ -553,7 +569,7 @@ test("insert_one_user_into_empty_list", ({override, mock_template}) => {
assert.ok($other_users_appended.selector.includes("user_circle_green"));
});
-test("insert_alice_then_fred", ({override, mock_template}) => {
+test("insert_alice_then_fred", ({override, override_rewire, mock_template}) => {
mock_template("presence_row.hbs", true, (_data, html) => html);
let $other_users_appended;
@@ -561,6 +577,7 @@ test("insert_alice_then_fred", ({override, mock_template}) => {
$other_users_appended = $element;
});
override(padded_widget, "update_padding", noop);
+ override_rewire(activity_ui, "update_presence_indicators", noop);
activity_ui.redraw_user(alice.user_id);
assert.ok($other_users_appended.selector.includes('data-user-id="1"'));
@@ -573,6 +590,7 @@ test("insert_alice_then_fred", ({override, mock_template}) => {
test("insert_fred_then_alice_then_rename, both as users matching view", ({
override,
+ override_rewire,
mock_template,
}) => {
mock_template("presence_row.hbs", true, (_data, html) => html);
@@ -585,6 +603,7 @@ test("insert_fred_then_alice_then_rename, both as users matching view", ({
$users_matching_view_appended = $element;
});
override(padded_widget, "update_padding", noop);
+ override_rewire(activity_ui, "update_presence_indicators", noop);
buddy_list_add_user_matching_view(alice.user_id, $alice_stub);
buddy_list_add_user_matching_view(fred.user_id, $fred_stub);
@@ -626,7 +645,11 @@ test("insert_fred_then_alice_then_rename, both as users matching view", ({
people.add_active_user(fred);
});
-test("insert_fred_then_alice_then_rename, both as other users", ({override, mock_template}) => {
+test("insert_fred_then_alice_then_rename, both as other users", ({
+ override,
+ override_rewire,
+ mock_template,
+}) => {
mock_template("presence_row.hbs", true, (_data, html) => html);
add_sub_and_set_as_current_narrow(rome_sub);
@@ -637,6 +660,7 @@ test("insert_fred_then_alice_then_rename, both as other users", ({override, mock
$other_users_appended = $element;
});
override(padded_widget, "update_padding", noop);
+ override_rewire(activity_ui, "update_presence_indicators", noop);
buddy_list_add_other_user(alice.user_id, $alice_stub);
buddy_list_add_other_user(fred.user_id, $fred_stub);
@@ -701,8 +725,9 @@ test("redraw_muted_user", () => {
assert.equal($("#buddy-list-users-matching-view").html(), "never-been-set");
});
-test("update_presence_info", ({override}) => {
+test("update_presence_info", ({override, override_rewire}) => {
override(pm_list, "update_private_messages", noop);
+ override_rewire(activity_ui, "update_presence_indicators", noop);
realm.realm_presence_disabled = false;
realm.server_presence_ping_interval_seconds = 60;
@@ -753,10 +778,11 @@ test("update_presence_info", ({override}) => {
assert.equal(presence.presence_info.get(inaccessible_user_id), undefined);
});
-test("initialize", ({override, mock_template}) => {
+test("initialize", ({override, override_rewire, mock_template}) => {
override(pm_list, "update_private_messages", noop);
override(watchdog, "check_for_unsuspend", noop);
override(buddy_list, "fill_screen_with_content", noop);
+ override_rewire(activity_ui, "update_presence_indicators", noop);
let payload;
override(channel, "post", (arg) => {