left_sidebar: Add unread markers to channel section headers.

This commit is contained in:
Evy Kassirer
2025-06-24 11:43:35 -07:00
committed by Tim Abbott
parent 739debf7b4
commit bc6b0cccf4
6 changed files with 75 additions and 3 deletions

View File

@@ -1,5 +1,6 @@
import $ from "jquery";
import _ from "lodash";
import assert from "minimalistic-assert";
import type {Filter} from "./filter.ts";
import {localstorage} from "./localstorage.ts";
@@ -9,6 +10,8 @@ import * as people from "./people.ts";
import * as resize from "./resize.ts";
import * as scheduled_messages from "./scheduled_messages.ts";
import * as settings_config from "./settings_config.ts";
import * as stream_list_sort from "./stream_list_sort.ts";
import * as sub_store from "./sub_store.ts";
import * as ui_util from "./ui_util.ts";
import * as unread from "./unread.ts";
@@ -86,6 +89,35 @@ export function update_dom_with_unread_counts(
ui_util.update_unread_count_in_dom($home_view_li, counts.home_unread_messages);
ui_util.update_unread_count_in_dom($back_to_streams, counts.stream_unread_messages);
let pinned_unread_count = 0;
let normal_unread_count = 0;
let inactive_unread_count = 0;
for (const [stream_id, stream_count_info] of counts.stream_count.entries()) {
const sub = sub_store.get(stream_id);
assert(sub);
if (sub.pin_to_top) {
pinned_unread_count += stream_count_info.unmuted_count;
} else if (stream_list_sort.has_recent_activity(sub)) {
normal_unread_count += stream_count_info.unmuted_count;
} else {
inactive_unread_count += stream_count_info.unmuted_count;
}
}
ui_util.update_unread_count_in_dom(
$("#stream-list-pinned-streams-container .markers-and-unreads"),
pinned_unread_count,
);
ui_util.update_unread_count_in_dom(
$("#stream-list-normal-streams-container .markers-and-unreads"),
normal_unread_count,
);
ui_util.update_unread_count_in_dom(
$("#stream-list-dormant-streams-container .markers-and-unreads"),
inactive_unread_count,
);
if (!skip_animations) {
animate_mention_changes($mentioned_li, counts.mentioned_message_count);
}

View File

@@ -17,6 +17,7 @@ import * as compose_actions from "./compose_actions.ts";
import type {Filter} from "./filter.ts";
import * as hash_util from "./hash_util.ts";
import * as keydown_util from "./keydown_util.ts";
import * as left_sidebar_navigation_area from "./left_sidebar_navigation_area.ts";
import {ListCursor} from "./list_cursor.ts";
import * as narrow_state from "./narrow_state.ts";
import * as pm_list from "./pm_list.ts";
@@ -321,6 +322,8 @@ export function build_stream_list(force_rerender: boolean): void {
add_sidebar_li(stream_id, $(`#stream-list-${section.id}`));
}
}
// Rerendering can moving channels between folders and change heading unread counts.
left_sidebar_navigation_area.update_dom_with_unread_counts(unread.get_counts(), false);
sidebar_ui.update_unread_counts_visibility();
collapse_collapsed_sections();
}
@@ -1124,7 +1127,10 @@ export function set_event_handlers({
"click",
".stream-list-section-container .add-stream-icon-container",
(e) => {
// To prevent toggling the header
// The browser default behavior of following the href on
// this link is correct. But we need to avoid triggering
// the click handler for the containing row, though (which
// would toggle the section).
e.stopPropagation();
},
);

View File

@@ -339,14 +339,14 @@
/* There's no three-dot menu here, but we still want the markers to line-up with
markers in other rows that do have three-dot menus. */
grid-template:
"arrow row-content add-channel three-dot-placeholder" var(
"arrow row-content add-channel markers-and-unreads three-dot-placeholder" var(
--line-height-sidebar-row-prominent
)
/ var(--right-sidebar-header-icon-toggle-width) minmax(0, 1fr) minmax(
0,
max-content
)
var(--left-sidebar-vdots-width);
minmax(0, max-content) var(--left-sidebar-vdots-width);
cursor: pointer;
background-color: var(--color-background);
position: sticky;
@@ -361,6 +361,10 @@
below. This extra margin prevents that overlap. */
margin-bottom: 1px;
.unread_count {
margin-right: var(--left-sidebar-unread-offset);
}
.add-stream-icon-container {
text-decoration: none;
grid-auto-columns: var(--left-sidebar-header-icon-width);
@@ -416,6 +420,17 @@
}
}
/* Only show section header unread counts when the section is collapsed
or when the header is being hovered over. */
#streams_list .stream-list-section-container:not(.collapsed) {
.stream-list-subsection-header:not(:hover) {
.unread_count,
.masked_unread_count {
visibility: hidden;
}
}
}
.direct-messages-container {
/* Properly offset all the grid rows
in the DM section. */

View File

@@ -9,6 +9,12 @@
<i class="add_stream_icon zulip-icon zulip-icon-square-plus" aria-hidden="true" ></i>
</a>
{{/if}}
<div class="markers-and-unreads">
<span class="unread_count quiet-count"></span>
<span class="masked_unread_count">
<i class="zulip-icon zulip-icon-masked-unread"></i>
</span>
</div>
</div>
<ul id="stream-list-{{id}}" class="stream-list-section"></ul>
</div>

View File

@@ -105,6 +105,7 @@ run_test("update_count_in_dom", () => {
mentioned_message_count: 222,
home_unread_messages: 333,
stream_unread_messages: 666,
stream_count: new Map(),
};
$(".selected-home-view").set_find_results(".sidebar-menu-icon", $("<menu-icon>"));
@@ -122,6 +123,9 @@ run_test("update_count_in_dom", () => {
make_elem($(".top_left_reminders"), "<reminders-count>");
make_elem($("#topics_header"), "<topics-count>");
make_elem($("#stream-list-pinned-streams-container .markers-and-unreads"), "<pinned-count>");
make_elem($("#stream-list-normal-streams-container .markers-and-unreads"), "<normal-count>");
make_elem($("#stream-list-dormant-streams-container .markers-and-unreads"), "<inactive-count>");
left_sidebar_navigation_area.update_dom_with_unread_counts(counts, false);
left_sidebar_navigation_area.update_starred_count(444, false);
@@ -134,6 +138,10 @@ run_test("update_count_in_dom", () => {
assert.equal($("<scheduled-count>").text(), "555");
assert.equal($("<reminders-count>").text(), "888");
assert.equal($("<topics-count>").text(), "666");
// TODO/channel-folders: Do proper data setup so these are a number.
assert.equal($("<pinned-count>").text(), "");
assert.equal($("<normal-count>").text(), "");
assert.equal($("<inactive-count>").text(), "");
counts.mentioned_message_count = 0;
scheduled_messages.get_count = () => 0;

View File

@@ -31,6 +31,11 @@ mock_esm("../src/unread", {
stream_is_muted: false,
muted_count: 0,
}),
get_counts: () => ({
mentioned_message_count: 222,
home_unread_messages: 333,
stream_unread_messages: 666,
}),
stream_has_any_unread_mentions: () => stream_has_any_unread_mentions,
stream_has_any_unmuted_mentions: () => noop,
});