stream_sidebar: Implement stream navigation behavior.

Clicking on the name of a stream in the left sidebar
now navigates to the top topic in the left sidebar
view of that stream, rather than an interleaved view.

Added an "interleaved" button to the stream popover row in the
left sidebar that appears only when the user hovers over it.

Fixes #26937.

Co-authored-by: Aman Agrawal <amanagr@zulip.com>
This commit is contained in:
sujal
2024-03-13 18:38:14 +05:30
committed by Tim Abbott
parent 9fc6b93347
commit 6589720424
6 changed files with 107 additions and 16 deletions

View File

@@ -33,6 +33,17 @@ async function expect_home(page: Page): Promise<void> {
]);
}
async function expect_verona_stream_top_topic(page: Page): Promise<void> {
const message_list_id = await common.get_current_msg_list_id(page, true);
await page.waitForSelector(`.message-list[data-message-list-id='${message_list_id}']`, {
visible: true,
});
await common.check_messages_sent(page, message_list_id, [
["Verona > test", ["verona test a", "verona test b", "verona test d"]],
]);
assert.strictEqual(await page.title(), "#Verona > test - Zulip Dev - Zulip");
}
async function expect_verona_stream(page: Page): Promise<void> {
const message_list_id = await common.get_current_msg_list_id(page, true);
await page.waitForSelector(`.message-list[data-message-list-id='${message_list_id}']`, {
@@ -313,8 +324,8 @@ async function expect_all_direct_messages(page: Page): Promise<void> {
async function test_narrow_by_clicking_the_left_sidebar(page: Page): Promise<void> {
console.log("Narrowing with left sidebar");
await page.click((await get_stream_li(page, "Verona")) + " a");
await expect_verona_stream(page);
await page.click((await get_stream_li(page, "Verona")) + " .stream-name");
await expect_verona_stream_top_topic(page);
await page.click("#left-sidebar-navigation-list .top_left_all_messages a");
await expect_home(page);
@@ -424,7 +435,7 @@ async function test_stream_search_filters_stream_list(page: Page): Promise<void>
await page.waitForSelector(await get_stream_li(page, "Denmark"), {hidden: true});
await page.waitForSelector(await get_stream_li(page, "Venice"), {hidden: true});
await page.click(await get_stream_li(page, "Verona"));
await expect_verona_stream(page);
await expect_verona_stream_top_topic(page);
assert.strictEqual(
await common.get_text_from_selector(page, ".stream-list-filter"),
"",

View File

@@ -4,9 +4,9 @@ import type {Page} from "puppeteer";
import * as common from "./lib/common";
async function navigate_using_left_sidebar(page: Page, click_target: string): Promise<void> {
console.log("Visiting #" + click_target);
await page.click(`#left-sidebar a[href='#${CSS.escape(click_target)}']`);
async function navigate_using_left_sidebar(page: Page, stream_name: string): Promise<void> {
console.log("Visiting #" + stream_name);
await page.click(`.stream-name[title="${stream_name}"]`);
await page.waitForSelector(`#message_feed_container`, {visible: true});
}
@@ -92,10 +92,7 @@ async function navigation_tests(page: Page): Promise<void> {
await navigate_to_settings(page);
const verona_id = await page.evaluate(() => zulip_test.get_stream_id("Verona"));
const verona_narrow = `narrow/stream/${verona_id}-Verona`;
await navigate_using_left_sidebar(page, verona_narrow);
await navigate_using_left_sidebar(page, "Verona");
await page.click("#left-sidebar-navigation-list .home-link");
await page.waitForSelector("#message_feed_container", {visible: true});
@@ -108,7 +105,7 @@ async function navigation_tests(page: Page): Promise<void> {
await navigate_to_settings(page);
await navigate_to_private_messages(page);
await navigate_to_subscriptions(page);
await navigate_using_left_sidebar(page, verona_narrow);
await navigate_using_left_sidebar(page, "Verona");
await test_reload_hash(page);

View File

@@ -20,16 +20,21 @@ import * as pm_list from "./pm_list";
import * as popovers from "./popovers";
import * as resize from "./resize";
import * as scroll_util from "./scroll_util";
import {web_channel_default_view_values} from "./settings_config";
import * as settings_data from "./settings_data";
import * as sidebar_ui from "./sidebar_ui";
import * as stream_data from "./stream_data";
import * as stream_list_sort from "./stream_list_sort";
import * as stream_topic_history from "./stream_topic_history";
import * as stream_topic_history_util from "./stream_topic_history_util";
import * as sub_store from "./sub_store";
import type {StreamSubscription} from "./sub_store";
import * as topic_list from "./topic_list";
import * as ui_util from "./ui_util";
import * as unread from "./unread";
import type {FullUnreadCountsData, StreamCountInfo} from "./unread";
import {user_settings} from "./user_settings";
import * as user_topics from "./user_topics";
let pending_stream_list_rerender = false;
let zoomed_in = false;
@@ -837,17 +842,63 @@ export function set_event_handlers({
}: {
on_stream_click: (stream_id: number, trigger: string) => void;
}): void {
$("#stream_filters").on("click", "li .subscription_block", (e) => {
$("#stream_filters").on("click", "li .subscription_block .stream-name", (e) => {
if (e.metaKey || e.ctrlKey || e.shiftKey) {
return;
}
const stream_id = stream_id_for_elt($(e.target).parents("li"));
on_stream_click(stream_id, "sidebar");
clear_and_hide_search();
e.preventDefault();
e.stopPropagation();
const stream_id = stream_id_for_elt($(e.target).parents("li"));
if (
user_settings.web_channel_default_view ===
web_channel_default_view_values.channel_feed.code
) {
on_stream_click(stream_id, "sidebar");
return;
}
let topics = stream_topic_history.get_recent_topic_names(stream_id);
const navigate_to_stream = (): void => {
let destination_url;
const top_unmuted_topic = topics.find(
(topic) => !user_topics.is_topic_muted(stream_id, topic),
);
const muted_topics = topics.find((topic) =>
user_topics.is_topic_muted(stream_id, topic),
);
if (top_unmuted_topic) {
destination_url = hash_util.by_stream_topic_url(stream_id, top_unmuted_topic);
browser_history.go_to_location(destination_url);
} else if (muted_topics) {
destination_url = hash_util.by_stream_topic_url(stream_id, muted_topics);
browser_history.go_to_location(destination_url);
} else {
on_stream_click(stream_id, "sidebar");
return;
}
};
if (topics.length === 0) {
stream_topic_history_util.get_server_history(stream_id, () => {
topics = stream_topic_history.get_recent_topic_names(stream_id);
if (topics.length === 0) {
on_stream_click(stream_id, "sidebar");
return;
}
navigate_to_stream();
return;
});
} else {
navigate_to_stream();
return;
}
});
$("#clear_search_stream_button").on("click", clear_search);

View File

@@ -15,8 +15,10 @@ import * as hash_util from "./hash_util";
import {$t, $t_html} from "./i18n";
import * as message_edit from "./message_edit";
import * as message_lists from "./message_lists";
import * as message_view from "./message_view";
import * as popover_menus from "./popover_menus";
import {left_sidebar_tippy_options} from "./popover_menus";
import {web_channel_default_view_values} from "./settings_config";
import * as settings_data from "./settings_data";
import * as stream_color from "./stream_color";
import * as stream_data from "./stream_data";
@@ -27,6 +29,7 @@ import * as sub_store from "./sub_store";
import * as ui_report from "./ui_report";
import * as ui_util from "./ui_util";
import * as unread_ops from "./unread_ops";
import {user_settings} from "./user_settings";
import * as util from "./util";
// In this module, we manage stream popovers
// that pop up from the left sidebar.
@@ -96,8 +99,12 @@ function build_stream_popover(opts) {
return;
}
const show_go_to_channel_feed =
user_settings.web_channel_default_view !==
web_channel_default_view_values.channel_feed.code;
const content = render_left_sidebar_stream_actions_popover({
stream: sub_store.get(stream_id),
show_go_to_channel_feed,
});
popover_menus.toggle_popover_menu(elt, {
@@ -116,6 +123,23 @@ function build_stream_popover(opts) {
const $popper = $(instance.popper);
ui_util.show_left_sidebar_menu_icon(elt);
// Go to channel feed instead of first topic.
$popper.on("click", ".stream-popover-go-to-channel-feed", (e) => {
e.preventDefault();
e.stopPropagation();
const sub = stream_popover_sub(e);
hide_stream_popover();
message_view.show(
[
{
operator: "stream",
operand: sub.name,
},
],
{trigger: "stream-popover"},
);
});
// Stream settings
$popper.on("click", ".open_stream_settings", (e) => {
const sub = stream_popover_sub(e);

View File

@@ -9,6 +9,14 @@
<span class="popover-stream-name">{{stream.name}}</span>
</li>
<li role="separator" class="popover-menu-separator"></li>
{{#if show_go_to_channel_feed}}
<li role="none" class="link-item popover-menu-inner-list-item">
<a role="menuitem" class="stream-popover-go-to-channel-feed popover-menu-link" tabindex="0">
<i class="popover-menu-icon zulip-icon zulip-icon-all-messages" aria-hidden="true"></i>
<span class="popover-menu-label">{{t "Go to channel feed" }}</span>
</a>
</li>
{{/if}}
<li role="none" class="link-item popover-menu-inner-list-item">
<a role="menuitem" class="open_stream_settings popover-menu-link" tabindex="0">
<i class="popover-menu-icon zulip-icon zulip-icon-gear" aria-hidden="true"></i>

View File

@@ -8,7 +8,7 @@
{{> stream_privacy }}
</span>
<a href="{{url}}" title="{{name}}" class="stream-name">{{name}}</a>
<span title="{{name}}" class="stream-name">{{name}}</span>
<div class="stream-markers-and-controls">
<span class="unread_mention_info"></span>