mirror of
https://github.com/zulip/zulip.git
synced 2025-11-04 05:53:43 +00:00
left_sidebar: Change channel sections to togglable sections.
This commit is contained in:
@@ -134,10 +134,10 @@ export function update_invite_user_option(): void {
|
||||
export function update_unread_counts_visibility(): void {
|
||||
const hidden = !user_settings.web_left_sidebar_unreads_count_summary;
|
||||
|
||||
const $streams_header: JQuery = $("#streams_header");
|
||||
const $channel_sections: JQuery = $(".stream-list-subsection-header");
|
||||
const $home_view_li: JQuery = $(".top_left_row");
|
||||
|
||||
for (const $el of [$home_view_li, $streams_header]) {
|
||||
for (const $el of [$home_view_li, $channel_sections]) {
|
||||
$el.toggleClass("hide-unread-messages-count", hidden);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,9 +6,9 @@ import * as tippy from "tippy.js";
|
||||
import render_filter_topics from "../templates/filter_topics.hbs";
|
||||
import render_go_to_channel_feed_tooltip from "../templates/go_to_channel_feed_tooltip.hbs";
|
||||
import render_go_to_channel_list_of_topics_tooltip from "../templates/go_to_channel_list_of_topics_tooltip.hbs";
|
||||
import render_stream_list_section_container from "../templates/stream_list_section_container.hbs";
|
||||
import render_stream_privacy from "../templates/stream_privacy.hbs";
|
||||
import render_stream_sidebar_row from "../templates/stream_sidebar_row.hbs";
|
||||
import render_stream_subheader from "../templates/streams_subheader.hbs";
|
||||
import render_subscribe_to_more_streams from "../templates/subscribe_to_more_streams.hbs";
|
||||
|
||||
import * as blueslip from "./blueslip.ts";
|
||||
@@ -16,7 +16,6 @@ import * as browser_history from "./browser_history.ts";
|
||||
import * as compose_actions from "./compose_actions.ts";
|
||||
import type {Filter} from "./filter.ts";
|
||||
import * as hash_util from "./hash_util.ts";
|
||||
import {$t} from "./i18n.ts";
|
||||
import * as keydown_util from "./keydown_util.ts";
|
||||
import {ListCursor} from "./list_cursor.ts";
|
||||
import * as narrow_state from "./narrow_state.ts";
|
||||
@@ -29,6 +28,7 @@ import * as settings_data from "./settings_data.ts";
|
||||
import * as sidebar_ui from "./sidebar_ui.ts";
|
||||
import * as stream_data from "./stream_data.ts";
|
||||
import * as stream_list_sort from "./stream_list_sort.ts";
|
||||
import type {StreamListSection} from "./stream_list_sort.ts";
|
||||
import * as stream_topic_history from "./stream_topic_history.ts";
|
||||
import * as stream_topic_history_util from "./stream_topic_history_util.ts";
|
||||
import * as sub_store from "./sub_store.ts";
|
||||
@@ -58,6 +58,8 @@ export function rewire_stream_cursor(value: typeof stream_cursor): void {
|
||||
|
||||
let has_scrolled = false;
|
||||
|
||||
const collapsed_sections = new Set<string>();
|
||||
|
||||
export function is_zoomed_in(): boolean {
|
||||
return zoomed_in;
|
||||
}
|
||||
@@ -260,6 +262,19 @@ export function create_initial_sidebar_rows(force_rerender = false): void {
|
||||
}
|
||||
}
|
||||
|
||||
export let stream_list_section_container_html = function (section: StreamListSection): string {
|
||||
return render_stream_list_section_container({
|
||||
id: section.id,
|
||||
section_title: section.section_title,
|
||||
});
|
||||
};
|
||||
|
||||
export function rewire_stream_list_section_container_html(
|
||||
value: typeof stream_list_section_container_html,
|
||||
): void {
|
||||
stream_list_section_container_html = value;
|
||||
}
|
||||
|
||||
export function build_stream_list(force_rerender: boolean): void {
|
||||
// The stream list in the left sidebar contains 3 sections:
|
||||
// pinned, normal, and dormant streams, with headings above them
|
||||
@@ -277,88 +292,53 @@ export function build_stream_list(force_rerender: boolean): void {
|
||||
return;
|
||||
}
|
||||
|
||||
const $parent = $("#stream_filters");
|
||||
const elems = [];
|
||||
|
||||
function add_sidebar_li(stream_id: number): void {
|
||||
function add_sidebar_li(stream_id: number, $list: JQuery): void {
|
||||
const sidebar_row = stream_sidebar.get_row(stream_id);
|
||||
assert(sidebar_row !== undefined);
|
||||
sidebar_row.update_whether_active();
|
||||
elems.push(sidebar_row.get_li());
|
||||
$list.append($(sidebar_row.get_li()));
|
||||
}
|
||||
|
||||
clear_topics();
|
||||
$parent.empty();
|
||||
$("#stream_filters").empty();
|
||||
for (const section of stream_groups.sections) {
|
||||
$("#stream_filters").append($(stream_list_section_container_html(section)));
|
||||
const is_empty = section.streams.length === 0 && section.muted_streams.length === 0;
|
||||
$(`#stream-list-${section.id}-container`).toggleClass("no-display", is_empty);
|
||||
|
||||
const any_pinned_streams =
|
||||
stream_groups.pinned_streams.length > 0 || stream_groups.muted_pinned_streams.length > 0;
|
||||
const any_normal_streams =
|
||||
stream_groups.normal_streams.length > 0 || stream_groups.muted_active_streams.length > 0;
|
||||
const any_dormant_streams = stream_groups.dormant_streams.length > 0;
|
||||
|
||||
const need_section_subheaders =
|
||||
(any_pinned_streams ? 1 : 0) +
|
||||
(any_normal_streams ? 1 : 0) +
|
||||
(any_dormant_streams ? 1 : 0) >=
|
||||
2;
|
||||
|
||||
if (any_pinned_streams && need_section_subheaders) {
|
||||
elems.push(
|
||||
$(
|
||||
render_stream_subheader({
|
||||
subheader_name: $t({
|
||||
defaultMessage: "Pinned",
|
||||
}),
|
||||
}),
|
||||
),
|
||||
);
|
||||
for (const stream_id of [...section.streams, ...section.muted_streams]) {
|
||||
add_sidebar_li(stream_id, $(`#stream-list-${section.id}`));
|
||||
}
|
||||
|
||||
for (const stream_id of stream_groups.pinned_streams) {
|
||||
add_sidebar_li(stream_id);
|
||||
}
|
||||
sidebar_ui.update_unread_counts_visibility();
|
||||
collapse_collapsed_sections();
|
||||
}
|
||||
|
||||
for (const stream_id of stream_groups.muted_pinned_streams) {
|
||||
add_sidebar_li(stream_id);
|
||||
function toggle_section_collapse($container: JQuery): void {
|
||||
$container.toggleClass("collapsed");
|
||||
const is_collapsed = $container.hasClass("collapsed");
|
||||
$container
|
||||
.find(".stream-list-section-toggle")
|
||||
.toggleClass("rotate-icon-down", !is_collapsed)
|
||||
.toggleClass("rotate-icon-right", is_collapsed);
|
||||
|
||||
const section_id = $container.attr("data-section-id")!;
|
||||
if (is_collapsed) {
|
||||
collapsed_sections.add(section_id);
|
||||
} else {
|
||||
collapsed_sections.delete(section_id);
|
||||
}
|
||||
}
|
||||
|
||||
if (any_normal_streams && need_section_subheaders) {
|
||||
elems.push(
|
||||
$(
|
||||
render_stream_subheader({
|
||||
subheader_name: $t({
|
||||
defaultMessage: "Active",
|
||||
}),
|
||||
}),
|
||||
),
|
||||
);
|
||||
function collapse_collapsed_sections(): void {
|
||||
for (const section_id of collapsed_sections) {
|
||||
const $container = $(`#stream-list-${section_id}-container`);
|
||||
$container.toggleClass("collapsed", true);
|
||||
$container
|
||||
.find(".stream-list-section-toggle")
|
||||
.toggleClass("rotate-icon-down", false)
|
||||
.toggleClass("rotate-icon-right", true);
|
||||
}
|
||||
|
||||
for (const stream_id of stream_groups.normal_streams) {
|
||||
add_sidebar_li(stream_id);
|
||||
}
|
||||
|
||||
for (const stream_id of stream_groups.muted_active_streams) {
|
||||
add_sidebar_li(stream_id);
|
||||
}
|
||||
|
||||
if (any_dormant_streams && need_section_subheaders) {
|
||||
elems.push(
|
||||
$(
|
||||
render_stream_subheader({
|
||||
subheader_name: $t({
|
||||
defaultMessage: "Inactive",
|
||||
}),
|
||||
}),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
for (const stream_id of stream_groups.dormant_streams) {
|
||||
add_sidebar_li(stream_id);
|
||||
}
|
||||
|
||||
$parent.append(elems); // eslint-disable-line no-jquery/no-append-html
|
||||
}
|
||||
|
||||
export function get_stream_li(stream_id: number): JQuery | undefined {
|
||||
@@ -416,11 +396,6 @@ export function zoom_in_topics(options: {stream_id: number | undefined}): void {
|
||||
|
||||
$("#streams_list").expectOne().removeClass("zoom-out").addClass("zoom-in");
|
||||
|
||||
// Hide pinned stream splitter
|
||||
$(".streams_subheader").each(function () {
|
||||
$(this).hide();
|
||||
});
|
||||
|
||||
$("#stream_filters li.narrow-filter").each(function () {
|
||||
const $elt = $(this);
|
||||
const stream_id = options.stream_id;
|
||||
@@ -438,11 +413,6 @@ export function zoom_in_topics(options: {stream_id: number | undefined}): void {
|
||||
}
|
||||
|
||||
export function zoom_out_topics(): void {
|
||||
// Show pinned stream splitter
|
||||
$(".streams_subheader").each(function () {
|
||||
$(this).show();
|
||||
});
|
||||
|
||||
$("#streams_list").expectOne().removeClass("zoom-in").addClass("zoom-out");
|
||||
$("#stream_filters li.narrow-filter").toggleClass("hide", false);
|
||||
// Remove search box for topics list from DOM.
|
||||
@@ -1113,6 +1083,15 @@ export function set_event_handlers({
|
||||
stream_cursor.clear();
|
||||
});
|
||||
$search_input.on("input", update_streams_for_search);
|
||||
|
||||
$("#streams_list").on(
|
||||
"click",
|
||||
".stream-list-section-container .stream-list-subsection-header",
|
||||
function (this: HTMLElement, e: JQuery.ClickEvent) {
|
||||
e.stopPropagation();
|
||||
toggle_section_collapse($(this).closest(".stream-list-section-container"));
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
export function searching(): boolean {
|
||||
@@ -1147,15 +1126,29 @@ export function clear_search(): void {
|
||||
$filter.trigger("blur");
|
||||
}
|
||||
|
||||
function scroll_stream_into_view($stream_li: JQuery): void {
|
||||
export let scroll_stream_into_view = function ($stream_li: JQuery): void {
|
||||
const $container = $("#left_sidebar_scroll_container");
|
||||
|
||||
if ($stream_li.length !== 1) {
|
||||
blueslip.error("Invalid stream_li was passed in");
|
||||
return;
|
||||
}
|
||||
const stream_header_height = $("#streams_header").outerHeight();
|
||||
scroll_util.scroll_element_into_container($stream_li, $container, stream_header_height);
|
||||
const stream_filter_height = $(".stream_search_section").outerHeight()!;
|
||||
const header_height = $stream_li
|
||||
.closest(".stream-list-section-container")
|
||||
.children(".stream-list-subsection-header")
|
||||
.outerHeight()!;
|
||||
scroll_util.scroll_element_into_container(
|
||||
$stream_li,
|
||||
$container,
|
||||
stream_filter_height + header_height,
|
||||
);
|
||||
// Note: If the stream is in a collapsed folder, we don't uncollapse the
|
||||
// folder.
|
||||
};
|
||||
|
||||
export function rewire_scroll_stream_into_view(value: typeof scroll_stream_into_view): void {
|
||||
scroll_stream_into_view = value;
|
||||
}
|
||||
|
||||
export function maybe_scroll_narrow_into_view(first_messages_fetch_done: boolean): void {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import assert from "minimalistic-assert";
|
||||
|
||||
import {$t} from "./i18n.ts";
|
||||
import * as settings_config from "./settings_config.ts";
|
||||
import * as stream_data from "./stream_data.ts";
|
||||
import * as sub_store from "./sub_store.ts";
|
||||
@@ -8,11 +9,7 @@ import {user_settings} from "./user_settings.ts";
|
||||
import * as util from "./util.ts";
|
||||
|
||||
let first_render_completed = false;
|
||||
let previous_pinned: number[] = [];
|
||||
let previous_normal: number[] = [];
|
||||
let previous_dormant: number[] = [];
|
||||
let previous_muted_active: number[] = [];
|
||||
let previous_muted_pinned: number[] = [];
|
||||
let current_sections: StreamListSection[] = [];
|
||||
let all_streams: number[] = [];
|
||||
|
||||
// Because we need to check whether we are filtering inactive streams
|
||||
@@ -71,13 +68,16 @@ export function has_recent_activity(sub: StreamSubscription): boolean {
|
||||
return sub.is_recently_active || sub.newly_subscribed;
|
||||
}
|
||||
|
||||
export type StreamListSection = {
|
||||
id: string;
|
||||
section_title: string;
|
||||
streams: number[];
|
||||
muted_streams: number[]; // Not used for the inactive section
|
||||
};
|
||||
|
||||
type StreamListSortResult = {
|
||||
same_as_before: boolean;
|
||||
pinned_streams: number[];
|
||||
normal_streams: number[];
|
||||
dormant_streams: number[];
|
||||
muted_pinned_streams: number[];
|
||||
muted_active_streams: number[];
|
||||
sections: StreamListSection[];
|
||||
};
|
||||
|
||||
export function sort_groups(stream_ids: number[], search_term: string): StreamListSortResult {
|
||||
@@ -95,74 +95,81 @@ export function sort_groups(stream_ids: number[], search_term: string): StreamLi
|
||||
return has_recent_activity(sub);
|
||||
}
|
||||
|
||||
const pinned_streams = [];
|
||||
const normal_streams = [];
|
||||
const muted_pinned_streams = [];
|
||||
const muted_active_streams = [];
|
||||
const dormant_streams = [];
|
||||
const pinned_section: StreamListSection = {
|
||||
id: "pinned-streams",
|
||||
section_title: $t({defaultMessage: "PINNED CHANNELS"}),
|
||||
streams: [],
|
||||
muted_streams: [],
|
||||
};
|
||||
const normal_section: StreamListSection = {
|
||||
id: "normal-streams",
|
||||
section_title: $t({defaultMessage: "ACTIVE CHANNELS"}),
|
||||
streams: [],
|
||||
muted_streams: [],
|
||||
};
|
||||
const dormant_section: StreamListSection = {
|
||||
id: "dormant-streams",
|
||||
section_title: $t({defaultMessage: "INACTIVE CHANNELS"}),
|
||||
streams: [],
|
||||
muted_streams: [], // Not used for the dormant section
|
||||
};
|
||||
|
||||
for (const stream_id of stream_ids) {
|
||||
const sub = sub_store.get(stream_id);
|
||||
assert(sub);
|
||||
const pinned = sub.pin_to_top;
|
||||
if (sub.is_archived) {
|
||||
continue;
|
||||
}
|
||||
if (pinned) {
|
||||
if (!sub.is_muted) {
|
||||
pinned_streams.push(stream_id);
|
||||
if (sub.pin_to_top) {
|
||||
if (sub.is_muted) {
|
||||
pinned_section.muted_streams.push(stream_id);
|
||||
} else {
|
||||
muted_pinned_streams.push(stream_id);
|
||||
pinned_section.streams.push(stream_id);
|
||||
}
|
||||
} else if (is_normal(sub)) {
|
||||
if (!sub.is_muted) {
|
||||
normal_streams.push(stream_id);
|
||||
if (sub.is_muted) {
|
||||
normal_section.muted_streams.push(stream_id);
|
||||
} else {
|
||||
muted_active_streams.push(stream_id);
|
||||
normal_section.streams.push(stream_id);
|
||||
}
|
||||
} else {
|
||||
dormant_streams.push(stream_id);
|
||||
dormant_section.streams.push(stream_id);
|
||||
}
|
||||
}
|
||||
|
||||
pinned_streams.sort(compare_function);
|
||||
normal_streams.sort(compare_function);
|
||||
muted_pinned_streams.sort(compare_function);
|
||||
muted_active_streams.sort(compare_function);
|
||||
dormant_streams.sort(compare_function);
|
||||
// This needs to have the same ordering as the order they're displayed in the sidebar.
|
||||
const new_sections = [pinned_section, normal_section, dormant_section];
|
||||
|
||||
for (const section of new_sections) {
|
||||
section.streams.sort(compare_function);
|
||||
section.muted_streams.sort(compare_function);
|
||||
}
|
||||
|
||||
const same_as_before =
|
||||
first_render_completed &&
|
||||
util.array_compare(previous_pinned, pinned_streams) &&
|
||||
util.array_compare(previous_normal, normal_streams) &&
|
||||
util.array_compare(previous_muted_pinned, muted_pinned_streams) &&
|
||||
util.array_compare(previous_muted_active, muted_active_streams) &&
|
||||
util.array_compare(previous_dormant, dormant_streams);
|
||||
new_sections.entries().every(([i, new_section]) => {
|
||||
const current_section = current_sections.at(i);
|
||||
return (
|
||||
current_section !== undefined &&
|
||||
new_section.id === current_section.id &&
|
||||
new_section.section_title === current_section.section_title &&
|
||||
util.array_compare(new_section.streams, current_section.streams) &&
|
||||
util.array_compare(new_section.muted_streams, current_section.muted_streams)
|
||||
);
|
||||
});
|
||||
|
||||
if (!same_as_before) {
|
||||
first_render_completed = true;
|
||||
previous_pinned = pinned_streams;
|
||||
previous_normal = normal_streams;
|
||||
previous_muted_pinned = muted_pinned_streams;
|
||||
previous_muted_active = muted_active_streams;
|
||||
previous_dormant = dormant_streams;
|
||||
|
||||
all_streams = [
|
||||
...pinned_streams,
|
||||
...muted_pinned_streams,
|
||||
...normal_streams,
|
||||
...muted_active_streams,
|
||||
...dormant_streams,
|
||||
];
|
||||
current_sections = new_sections;
|
||||
all_streams = new_sections.flatMap((section) => [
|
||||
...section.streams,
|
||||
...section.muted_streams,
|
||||
]);
|
||||
}
|
||||
|
||||
return {
|
||||
same_as_before,
|
||||
pinned_streams,
|
||||
normal_streams,
|
||||
dormant_streams,
|
||||
muted_pinned_streams,
|
||||
muted_active_streams,
|
||||
sections: new_sections,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -81,7 +81,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
.selected-home-view,
|
||||
#left-sidebar-navigation-list .selected-home-view,
|
||||
#streams_header {
|
||||
&.hide-unread-messages-count {
|
||||
.masked_unread_count {
|
||||
@@ -101,7 +101,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
.selected-home-view:hover,
|
||||
#left-sidebar-navigation-list .selected-home-view:hover,
|
||||
#streams_header:hover,
|
||||
.selected-home-view.top-left-active-filter {
|
||||
&.hide-unread-messages-count {
|
||||
@@ -310,6 +310,71 @@
|
||||
}
|
||||
}
|
||||
|
||||
.stream_search_section {
|
||||
position: sticky;
|
||||
top: 0;
|
||||
/* Must be more than .stream-list-subsection-header */
|
||||
z-index: 3;
|
||||
/* Must be padding not margin so that the sticky headers don't show behind it */
|
||||
padding: var(--left-sidebar-sections-vertical-gutter)
|
||||
var(--left-sidebar-right-margin) 3px 5px;
|
||||
}
|
||||
|
||||
.stream-list-subsection-header {
|
||||
display: grid;
|
||||
align-items: center;
|
||||
grid-template:
|
||||
"arrow row-content" var(--line-height-sidebar-row-prominent)
|
||||
/ var(--right-sidebar-header-icon-toggle-width) minmax(0, 1fr);
|
||||
cursor: pointer;
|
||||
background-color: var(--color-background);
|
||||
position: sticky;
|
||||
/* Input is 31px tall at 16px/1em.
|
||||
Input container has 8px and 3px top/bottom padding = 11px total padding */
|
||||
top: calc(1.9375em + 11px);
|
||||
/* Must be more than .sidebar-topic-check and less than #stream-search-and-add */
|
||||
z-index: 2;
|
||||
color: var(--color-text-default);
|
||||
/* There seems to be a bug where when the header returns to normal position after
|
||||
being sticky, it's 0.5px below its actual position and thus overlaps the channel
|
||||
below. This extra margin prevents that overlap. */
|
||||
margin-bottom: 1px;
|
||||
|
||||
&:hover {
|
||||
background-color: var(--color-background-opaque-hover-narrow-filter);
|
||||
box-shadow: inset 0 0 0 1px var(--color-shadow-sidebar-row-hover);
|
||||
/* We only set the border radius on the hover/popover states,
|
||||
so as to prevent the background on highlighted channels
|
||||
from bleeding through. */
|
||||
border-radius: 4px;
|
||||
|
||||
.left-sidebar-title,
|
||||
.stream-list-section-toggle {
|
||||
opacity: var(--opacity-sidebar-heading-hover);
|
||||
}
|
||||
}
|
||||
|
||||
.stream-list-section-toggle {
|
||||
color: var(--color-text-sidebar-heading);
|
||||
opacity: var(--opacity-sidebar-heading-icon);
|
||||
justify-self: center;
|
||||
}
|
||||
}
|
||||
|
||||
.stream-list-section {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.stream-list-section-container.no-display {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.stream-list-section-container.collapsed {
|
||||
.narrow-filter {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.direct-messages-container {
|
||||
/* Properly offset all the grid rows
|
||||
in the DM section. */
|
||||
@@ -1407,7 +1472,7 @@ li.top_left_scheduled_messages {
|
||||
/* As a grid item, adjust the checkmark's z-index here so
|
||||
that the background color appears above the grouping
|
||||
bracket's bottom line. Its value must less than
|
||||
the z-index set on the #streams_header selector. */
|
||||
the z-index set on .stream-list-subsection-header */
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
@@ -1871,49 +1936,6 @@ li.topic-list-item {
|
||||
}
|
||||
}
|
||||
|
||||
.streams_subheader {
|
||||
/* 14px at 16px/1em */
|
||||
font-size: 0.875em;
|
||||
font-weight: normal;
|
||||
/* 16px line-height at 0.8em (11.2px at 14px legacy em) */
|
||||
line-height: 1.4286em;
|
||||
letter-spacing: 0.04em;
|
||||
padding-left: var(--left-sidebar-toggle-width-offset);
|
||||
cursor: pointer;
|
||||
text-align: center;
|
||||
margin-right: var(--left-sidebar-right-margin);
|
||||
|
||||
& .streams-subheader-wrapper {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
width: 100%;
|
||||
left: 0.5em;
|
||||
right: 0.5em;
|
||||
color: var(--color-text-sidebar-base);
|
||||
}
|
||||
|
||||
& .streams-subheader-wrapper::before,
|
||||
.streams-subheader-wrapper::after {
|
||||
content: " ";
|
||||
flex: 1 1;
|
||||
vertical-align: middle;
|
||||
margin: auto;
|
||||
border-top: 1px solid var(--color-border-sidebar-subheader);
|
||||
}
|
||||
|
||||
& .streams-subheader-wrapper::before {
|
||||
margin-right: 0.2em;
|
||||
}
|
||||
|
||||
& .streams-subheader-wrapper::after {
|
||||
margin-left: 0.2em;
|
||||
}
|
||||
|
||||
.streams-subheader-name {
|
||||
opacity: 0.4;
|
||||
}
|
||||
}
|
||||
|
||||
.zero_count {
|
||||
visibility: hidden;
|
||||
}
|
||||
@@ -1929,13 +1951,14 @@ li.topic-list-item {
|
||||
|
||||
.narrow-filter > .bottom_left_row {
|
||||
position: sticky;
|
||||
/* We subtract a quarter pixel of space to correct
|
||||
for possible bleedthrough under certain viewing
|
||||
conditions (e.g., external monitors.) This same
|
||||
technique is used on #streams_header. */
|
||||
/* We need to hold the space where the BACK TO CHANNELS
|
||||
line sits, so the channel info doesn't run over the
|
||||
top of it when scrolling down. These are the same
|
||||
variables for setting the space on the BACK TO CHANNELS
|
||||
grid row plus its top padding: */
|
||||
top: calc(
|
||||
var(--left-sidebar-sections-vertical-gutter) +
|
||||
var(--line-height-sidebar-row-prominent) - 0.25px
|
||||
var(--line-height-sidebar-row-prominent) +
|
||||
var(--left-sidebar-sections-vertical-gutter)
|
||||
);
|
||||
z-index: 2;
|
||||
padding-bottom: 1px;
|
||||
|
||||
@@ -195,7 +195,8 @@
|
||||
</div>
|
||||
|
||||
<div id="streams_list" class="zoom-out">
|
||||
<div id="streams_header" class="showing-stream-search-section zoom-in-hide">
|
||||
{{!-- TODO: Future commits will hide #streams_header completely, but for smaller reviewable commits this commit just hides the header for now --}}
|
||||
<div id="streams_header" style="display: none;" class="showing-stream-search-section zoom-in-hide">
|
||||
<h4 class="left-sidebar-title"><span class="streams-tooltip-target">{{t 'CHANNELS' }}</span></h4>
|
||||
<div class="left-sidebar-controls">
|
||||
<span id="add_streams_tooltip" class="hidden-for-spectators">
|
||||
@@ -208,12 +209,10 @@
|
||||
<i class="zulip-icon zulip-icon-masked-unread"></i>
|
||||
</span>
|
||||
</div>
|
||||
<div class="left-sidebar-filter-input-container">
|
||||
</div>
|
||||
{{#> input_wrapper input_type="filter-input" custom_classes="stream_search_section" icon="search" input_button_icon="close"}}
|
||||
<input type="text" class="input-element stream-list-filter home-page-input" autocomplete="off" placeholder="{{t 'Filter channels' }}" />
|
||||
{{/input_wrapper}}
|
||||
</div>
|
||||
</div>
|
||||
<div id="topics_header">
|
||||
<a class="show-all-streams trigger-click-on-enter" tabindex="0">{{t 'Back to channels' }}</a> <span class="unread_count quiet-count"></span>
|
||||
</div>
|
||||
|
||||
9
web/templates/stream_list_section_container.hbs
Normal file
9
web/templates/stream_list_section_container.hbs
Normal file
@@ -0,0 +1,9 @@
|
||||
<div id="stream-list-{{id}}-container" data-section-id="{{id}}" class="stream-list-section-container">
|
||||
<div class="stream-list-subsection-header zoom-in-hide">
|
||||
<i class="stream-list-section-toggle zulip-icon zulip-icon-heading-triangle-right rotate-icon-down" aria-hidden="true"></i>
|
||||
<h4 class="left-sidebar-title">
|
||||
{{section_title}}
|
||||
</h4>
|
||||
</div>
|
||||
<ul id="stream-list-{{id}}" class="stream-list-section"></ul>
|
||||
</div>
|
||||
@@ -1,7 +0,0 @@
|
||||
<div class="streams_subheader">
|
||||
<span class="streams-subheader-wrapper">
|
||||
<span class="streams-subheader-name">
|
||||
{{ subheader_name }}
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
@@ -21,7 +21,7 @@ let unread_unmuted_count;
|
||||
let stream_has_any_unread_mentions;
|
||||
|
||||
const topic_list = mock_esm("../src/topic_list");
|
||||
const scroll_util = mock_esm("../src/scroll_util", {
|
||||
mock_esm("../src/scroll_util", {
|
||||
scroll_element_into_container() {},
|
||||
get_scroll_element: ($element) => $element,
|
||||
});
|
||||
@@ -101,11 +101,6 @@ const social = {
|
||||
can_send_message_group: everyone_group.id,
|
||||
};
|
||||
|
||||
// flag to check if subheader is rendered
|
||||
let pinned_subheader_flag = false;
|
||||
let active_subheader_flag = false;
|
||||
let inactive_subheader_flag = false;
|
||||
|
||||
function create_devel_sidebar_row({mock_template}) {
|
||||
const $devel_count = $.create("devel-count");
|
||||
const $subscription_block = $.create("devel-block");
|
||||
@@ -152,22 +147,6 @@ function create_social_sidebar_row({mock_template}) {
|
||||
assert.equal($social_unread_mention_info.text(), "@");
|
||||
}
|
||||
|
||||
function create_stream_subheader({mock_template}) {
|
||||
mock_template("streams_subheader.hbs", false, (data) => {
|
||||
if (data.subheader_name === "translated: Pinned") {
|
||||
pinned_subheader_flag = true;
|
||||
return "<pinned-subheader-stub>";
|
||||
} else if (data.subheader_name === "translated: Active") {
|
||||
active_subheader_flag = true;
|
||||
return "<active-subheader-stub>";
|
||||
}
|
||||
|
||||
assert.ok(data.subheader_name === "translated: Inactive");
|
||||
inactive_subheader_flag = true;
|
||||
return "<inactive-subheader-stub>";
|
||||
});
|
||||
}
|
||||
|
||||
function test_ui(label, f) {
|
||||
run_test(label, (helpers) => {
|
||||
stream_data.clear_subscriptions();
|
||||
@@ -176,48 +155,46 @@ function test_ui(label, f) {
|
||||
});
|
||||
}
|
||||
|
||||
test_ui("create_sidebar_row", ({override, mock_template}) => {
|
||||
test_ui("create_sidebar_row", ({override, override_rewire, mock_template}) => {
|
||||
// Make a couple calls to create_sidebar_row() and make sure they
|
||||
// generate the right markup as well as play nice with get_stream_li().
|
||||
override(user_settings, "demote_inactive_streams", 1);
|
||||
const appended_sections = [];
|
||||
override_rewire(stream_list, "stream_list_section_container_html", (section) => {
|
||||
appended_sections.push(section.id);
|
||||
return `<stub-section-${section.id}>`;
|
||||
});
|
||||
|
||||
const pinned_streams = [];
|
||||
$("#stream-list-pinned-streams").append = (stream) => {
|
||||
pinned_streams.push(stream);
|
||||
};
|
||||
const normal_streams = [];
|
||||
$("#stream-list-normal-streams").append = (stream) => {
|
||||
normal_streams.push(stream);
|
||||
};
|
||||
|
||||
stream_data.add_sub(devel);
|
||||
stream_data.add_sub(social);
|
||||
|
||||
create_devel_sidebar_row({mock_template});
|
||||
create_social_sidebar_row({mock_template});
|
||||
create_stream_subheader({mock_template});
|
||||
|
||||
topic_list.get_stream_li = noop;
|
||||
|
||||
const $pinned_subheader = $("<pinned-subheader-stub>");
|
||||
const $active_subheader = $("<active-subheader-stub>");
|
||||
const $devel_sidebar = $("<devel-sidebar-row-stub>");
|
||||
const $social_sidebar = $("<social-sidebar-row-stub>");
|
||||
|
||||
let appended_elems;
|
||||
$("#stream_filters").append = (elems) => {
|
||||
appended_elems = elems;
|
||||
};
|
||||
|
||||
let topics_closed;
|
||||
topic_list.close = () => {
|
||||
topics_closed = true;
|
||||
};
|
||||
|
||||
stream_list.build_stream_list();
|
||||
|
||||
assert.ok(topics_closed);
|
||||
const expected_elems = [
|
||||
$pinned_subheader, // separator
|
||||
$devel_sidebar, // pinned
|
||||
$active_subheader, // separator
|
||||
$social_sidebar, // not pinned
|
||||
];
|
||||
assert.deepEqual(appended_sections, ["pinned-streams", "normal-streams", "dormant-streams"]);
|
||||
|
||||
assert.deepEqual(appended_elems, expected_elems);
|
||||
assert.ok(pinned_subheader_flag);
|
||||
assert.ok(active_subheader_flag);
|
||||
assert.deepEqual(pinned_streams, [$devel_sidebar]);
|
||||
assert.deepEqual(normal_streams, [$social_sidebar]);
|
||||
|
||||
const $social_li = $("<social-sidebar-row-stub>");
|
||||
const stream_id = social.stream_id;
|
||||
@@ -267,8 +244,6 @@ test_ui("pinned_streams_never_inactive", ({mock_template}) => {
|
||||
|
||||
create_devel_sidebar_row({mock_template});
|
||||
create_social_sidebar_row({mock_template});
|
||||
create_stream_subheader({mock_template});
|
||||
|
||||
// non-pinned streams can be made inactive
|
||||
const $social_sidebar = $("<social-sidebar-row-stub>");
|
||||
let stream_id = social.stream_id;
|
||||
@@ -397,15 +372,6 @@ function elem($obj) {
|
||||
test_ui("zoom_in_and_zoom_out", ({mock_template}) => {
|
||||
topic_list.setup_topic_search_typeahead = noop;
|
||||
|
||||
const $splitter = $.create("<active-subheader-stub>");
|
||||
|
||||
$splitter.show();
|
||||
assert.ok($splitter.visible());
|
||||
|
||||
$.create(".streams_subheader", {
|
||||
children: [elem($splitter)],
|
||||
});
|
||||
|
||||
const $stream_li1 = $.create("stream1 stub");
|
||||
const $stream_li2 = $.create("stream2 stub");
|
||||
|
||||
@@ -439,7 +405,6 @@ test_ui("zoom_in_and_zoom_out", ({mock_template}) => {
|
||||
});
|
||||
stream_list.zoom_in_topics({stream_id: 42});
|
||||
|
||||
assert.ok(!$splitter.visible());
|
||||
assert.ok(!$stream_li1.hasClass("hide"));
|
||||
assert.ok($stream_li2.hasClass("hide"));
|
||||
assert.ok($("#streams_list").hasClass("zoom-in"));
|
||||
@@ -456,22 +421,20 @@ test_ui("zoom_in_and_zoom_out", ({mock_template}) => {
|
||||
};
|
||||
stream_list.zoom_out_topics({$stream_li: $stream_li1});
|
||||
|
||||
assert.ok($splitter.visible());
|
||||
assert.ok(!$stream_li1.hasClass("hide"));
|
||||
assert.ok(!$stream_li2.hasClass("hide"));
|
||||
assert.ok($("#streams_list").hasClass("zoom-out"));
|
||||
assert.ok(!filter_topics_appended);
|
||||
});
|
||||
|
||||
test_ui("narrowing", ({mock_template}) => {
|
||||
create_stream_subheader({mock_template});
|
||||
test_ui("narrowing", ({override_rewire}) => {
|
||||
initialize_stream_data();
|
||||
|
||||
topic_list.close = noop;
|
||||
topic_list.rebuild_left_sidebar = noop;
|
||||
topic_list.active_stream_id = noop;
|
||||
topic_list.get_stream_li = noop;
|
||||
$("#streams_header").outerHeight = () => 0;
|
||||
override_rewire(stream_list, "scroll_stream_into_view", noop);
|
||||
|
||||
assert.ok(!$("<devel-sidebar-row-stub>").hasClass("active-filter"));
|
||||
|
||||
@@ -529,44 +492,45 @@ test_ui("focus_user_filter", () => {
|
||||
click_handler(e);
|
||||
});
|
||||
|
||||
test_ui("sort_streams", ({mock_template}) => {
|
||||
create_stream_subheader({mock_template});
|
||||
// Set subheader flag to false
|
||||
pinned_subheader_flag = false;
|
||||
active_subheader_flag = false;
|
||||
inactive_subheader_flag = false;
|
||||
|
||||
test_ui("sort_streams", ({override_rewire}) => {
|
||||
// Get coverage on early-exit.
|
||||
stream_list.build_stream_list();
|
||||
|
||||
initialize_stream_data();
|
||||
|
||||
let appended_elems;
|
||||
$("#stream_filters").append = (elems) => {
|
||||
appended_elems = elems;
|
||||
const appended_sections = [];
|
||||
override_rewire(stream_list, "stream_list_section_container_html", (section) => {
|
||||
appended_sections.push(section.id);
|
||||
return `<stub-section-${section.id}>`;
|
||||
});
|
||||
|
||||
const pinned_streams = [];
|
||||
$("#stream-list-pinned-streams").append = (stream) => {
|
||||
pinned_streams.push(stream);
|
||||
};
|
||||
const normal_streams = [];
|
||||
$("#stream-list-normal-streams").append = (stream) => {
|
||||
normal_streams.push(stream);
|
||||
};
|
||||
const inactive_streams = [];
|
||||
$("#stream-list-dormant-streams").append = (stream) => {
|
||||
inactive_streams.push(stream);
|
||||
};
|
||||
|
||||
stream_list.build_stream_list(true);
|
||||
|
||||
const $pinned_subheader = $("<pinned-subheader-stub>");
|
||||
const $active_subheader = $("<active-subheader-stub>");
|
||||
const $inactive_subheader = $("<inactive-subheader-stub>");
|
||||
const expected_elems = [
|
||||
$pinned_subheader,
|
||||
assert.deepEqual(appended_sections, ["pinned-streams", "normal-streams", "dormant-streams"]);
|
||||
|
||||
assert.deepEqual(pinned_streams, [
|
||||
$("<devel-sidebar-row-stub>"),
|
||||
$("<Rome-sidebar-row-stub>"),
|
||||
$("<test-sidebar-row-stub>"),
|
||||
$active_subheader,
|
||||
]);
|
||||
assert.deepEqual(normal_streams, [
|
||||
$("<announce-sidebar-row-stub>"),
|
||||
$("<Denmark-sidebar-row-stub>"),
|
||||
$inactive_subheader,
|
||||
$("<cars-sidebar-row-stub>"),
|
||||
];
|
||||
|
||||
assert.deepEqual(appended_elems, expected_elems);
|
||||
assert.ok(pinned_subheader_flag);
|
||||
assert.ok(active_subheader_flag);
|
||||
assert.ok(inactive_subheader_flag);
|
||||
]);
|
||||
assert.deepEqual(inactive_streams, [$("<cars-sidebar-row-stub>")]);
|
||||
|
||||
const streams = stream_list_sort.get_stream_ids();
|
||||
|
||||
@@ -589,13 +553,7 @@ test_ui("sort_streams", ({mock_template}) => {
|
||||
assert.ok(!stream_list.stream_sidebar.has_row_for(stream_id));
|
||||
});
|
||||
|
||||
test_ui("separators_only_pinned_and_dormant", ({mock_template}) => {
|
||||
// Test only pinned and dormant streams
|
||||
|
||||
create_stream_subheader({mock_template});
|
||||
pinned_subheader_flag = false;
|
||||
inactive_subheader_flag = false;
|
||||
|
||||
test_ui("separators_only_pinned_and_dormant", ({override_rewire}) => {
|
||||
// Get coverage on early-exit.
|
||||
stream_list.build_stream_list();
|
||||
|
||||
@@ -630,73 +588,31 @@ test_ui("separators_only_pinned_and_dormant", ({mock_template}) => {
|
||||
};
|
||||
add_row(DenmarkSub);
|
||||
|
||||
let appended_elems;
|
||||
$("#stream_filters").append = (elems) => {
|
||||
appended_elems = elems;
|
||||
const appended_sections = [];
|
||||
override_rewire(stream_list, "stream_list_section_container_html", (section) => {
|
||||
appended_sections.push(section.id);
|
||||
return `<stub-section-${section.id}>`;
|
||||
});
|
||||
const pinned_streams = [];
|
||||
$("#stream-list-pinned-streams").append = (stream) => {
|
||||
pinned_streams.push(stream);
|
||||
};
|
||||
const inactive_streams = [];
|
||||
$("#stream-list-dormant-streams").append = (stream) => {
|
||||
inactive_streams.push(stream);
|
||||
};
|
||||
|
||||
stream_list.build_stream_list();
|
||||
|
||||
const $pinned_subheader = $("<pinned-subheader-stub>");
|
||||
const $inactive_subheader = $("<inactive-subheader-stub>");
|
||||
const expected_elems = [
|
||||
$pinned_subheader, // pinned
|
||||
$("<devel-sidebar-row-stub>"),
|
||||
$("<Rome-sidebar-row-stub>"),
|
||||
$inactive_subheader, // dormant
|
||||
$("<Denmark-sidebar-row-stub>"),
|
||||
];
|
||||
assert.deepEqual(appended_sections, ["pinned-streams", "normal-streams", "dormant-streams"]);
|
||||
|
||||
assert.deepEqual(appended_elems, expected_elems);
|
||||
assert.ok(pinned_subheader_flag);
|
||||
assert.ok(inactive_subheader_flag);
|
||||
});
|
||||
|
||||
test_ui("separators_only_pinned", () => {
|
||||
// Test only pinned streams
|
||||
// Get coverage on early-exit.
|
||||
stream_list.build_stream_list();
|
||||
|
||||
// pinned streams
|
||||
const develSub = {
|
||||
name: "devel",
|
||||
stream_id: 1000,
|
||||
color: "blue",
|
||||
pin_to_top: true,
|
||||
subscribed: true,
|
||||
};
|
||||
add_row(develSub);
|
||||
|
||||
const RomeSub = {
|
||||
name: "Rome",
|
||||
stream_id: 2000,
|
||||
color: "blue",
|
||||
pin_to_top: true,
|
||||
subscribed: true,
|
||||
};
|
||||
add_row(RomeSub);
|
||||
|
||||
let appended_elems;
|
||||
$("#stream_filters").append = (elems) => {
|
||||
appended_elems = elems;
|
||||
};
|
||||
|
||||
stream_list.build_stream_list();
|
||||
const expected_elems = [
|
||||
// no section sub-header since there is only one section
|
||||
$("<devel-sidebar-row-stub>"),
|
||||
$("<Rome-sidebar-row-stub>"),
|
||||
// no separator at the end as no stream follows
|
||||
];
|
||||
|
||||
assert.deepEqual(appended_elems, expected_elems);
|
||||
assert.deepEqual(pinned_streams, [$("<devel-sidebar-row-stub>"), $("<Rome-sidebar-row-stub>")]);
|
||||
assert.deepEqual(inactive_streams, [$("<Denmark-sidebar-row-stub>")]);
|
||||
});
|
||||
|
||||
test_ui("rename_stream", ({mock_template, override}) => {
|
||||
override(user_settings, "web_stream_unreads_count_display_policy", 3);
|
||||
override(current_user, "user_id", me.user_id);
|
||||
|
||||
create_stream_subheader({mock_template});
|
||||
initialize_stream_data();
|
||||
|
||||
const sub = stream_data.get_sub_by_name("devel");
|
||||
@@ -737,7 +653,7 @@ test_ui("rename_stream", ({mock_template, override}) => {
|
||||
develSub.name = "devel"; // Resets
|
||||
});
|
||||
|
||||
test_ui("refresh_pin", ({override, override_rewire, mock_template}) => {
|
||||
test_ui("refresh_pin", ({override_rewire, mock_template}) => {
|
||||
initialize_stream_data();
|
||||
|
||||
const sub = {
|
||||
@@ -762,10 +678,9 @@ test_ui("refresh_pin", ({override, override_rewire, mock_template}) => {
|
||||
|
||||
override_rewire(stream_list, "update_count_in_dom", noop);
|
||||
$("#stream_filters").append = noop;
|
||||
$("#streams_header").outerHeight = () => 0;
|
||||
|
||||
let scrolled;
|
||||
override(scroll_util, "scroll_element_into_container", ($li) => {
|
||||
override_rewire(stream_list, "scroll_stream_into_view", ($li) => {
|
||||
if ($li === $li_stub) {
|
||||
scrolled = true;
|
||||
}
|
||||
|
||||
@@ -100,11 +100,26 @@ function test(label, f) {
|
||||
test("no_subscribed_streams", () => {
|
||||
const sorted = sort_groups("");
|
||||
assert.deepEqual(sorted, {
|
||||
dormant_streams: [],
|
||||
muted_active_streams: [],
|
||||
muted_pinned_streams: [],
|
||||
normal_streams: [],
|
||||
pinned_streams: [],
|
||||
sections: [
|
||||
{
|
||||
id: "pinned-streams",
|
||||
muted_streams: [],
|
||||
section_title: "translated: PINNED CHANNELS",
|
||||
streams: [],
|
||||
},
|
||||
{
|
||||
id: "normal-streams",
|
||||
muted_streams: [],
|
||||
section_title: "translated: ACTIVE CHANNELS",
|
||||
streams: [],
|
||||
},
|
||||
{
|
||||
id: "dormant-streams",
|
||||
muted_streams: [],
|
||||
section_title: "translated: INACTIVE CHANNELS",
|
||||
streams: [],
|
||||
},
|
||||
],
|
||||
same_as_before: sorted.same_as_before,
|
||||
});
|
||||
assert.equal(stream_list_sort.first_stream_id(), undefined);
|
||||
@@ -122,16 +137,22 @@ test("basics", () => {
|
||||
stream_data.add_sub(archived);
|
||||
|
||||
// Test sorting into categories/alphabetized
|
||||
let sorted = sort_groups("");
|
||||
assert.deepEqual(sorted.pinned_streams, [scalene.stream_id]);
|
||||
assert.deepEqual(sorted.normal_streams, [
|
||||
let sorted_sections = sort_groups("").sections;
|
||||
const pinned = sorted_sections[0];
|
||||
assert.deepEqual(pinned.id, "pinned-streams");
|
||||
assert.deepEqual(pinned.streams, [scalene.stream_id]);
|
||||
assert.deepEqual(pinned.muted_streams, [muted_pinned.stream_id]);
|
||||
const normal = sorted_sections[1];
|
||||
assert.deepEqual(normal.id, "normal-streams");
|
||||
assert.deepEqual(normal.streams, [
|
||||
clarinet.stream_id,
|
||||
fast_tortoise.stream_id,
|
||||
stream_hyphen_underscore_slash_colon.stream_id,
|
||||
]);
|
||||
assert.deepEqual(sorted.muted_pinned_streams, [muted_pinned.stream_id]);
|
||||
assert.deepEqual(sorted.muted_active_streams, [muted_active.stream_id]);
|
||||
assert.deepEqual(sorted.dormant_streams, [pneumonia.stream_id]);
|
||||
assert.deepEqual(normal.muted_streams, [muted_active.stream_id]);
|
||||
const dormant = sorted_sections[2];
|
||||
assert.deepEqual(dormant.id, "dormant-streams");
|
||||
assert.deepEqual(dormant.streams, [pneumonia.stream_id]);
|
||||
|
||||
// Test cursor helpers.
|
||||
assert.equal(stream_list_sort.first_stream_id(), scalene.stream_id);
|
||||
@@ -156,53 +177,70 @@ test("basics", () => {
|
||||
assert.equal(stream_list_sort.next_stream_id(pneumonia.stream_id), undefined);
|
||||
|
||||
// Test filtering
|
||||
sorted = sort_groups("s");
|
||||
assert.deepEqual(sorted.pinned_streams, [scalene.stream_id]);
|
||||
assert.deepEqual(sorted.normal_streams, [stream_hyphen_underscore_slash_colon.stream_id]);
|
||||
assert.deepEqual(sorted.dormant_streams, []);
|
||||
sorted_sections = sort_groups("s").sections;
|
||||
assert.deepEqual(sorted_sections.length, 3);
|
||||
assert.deepEqual(sorted_sections[0].id, "pinned-streams");
|
||||
assert.deepEqual(sorted_sections[0].streams, [scalene.stream_id]);
|
||||
assert.deepEqual(sorted_sections[1].id, "normal-streams");
|
||||
assert.deepEqual(sorted_sections[1].streams, [stream_hyphen_underscore_slash_colon.stream_id]);
|
||||
assert.deepEqual(sorted_sections[2].streams, []);
|
||||
|
||||
assert.equal(stream_list_sort.prev_stream_id(clarinet.stream_id), undefined);
|
||||
|
||||
assert.equal(stream_list_sort.next_stream_id(clarinet.stream_id), undefined);
|
||||
|
||||
// Test searching entire word, case-insensitive
|
||||
sorted = sort_groups("PnEuMoNiA");
|
||||
assert.deepEqual(sorted.pinned_streams, []);
|
||||
assert.deepEqual(sorted.normal_streams, []);
|
||||
assert.deepEqual(sorted.dormant_streams, [pneumonia.stream_id]);
|
||||
sorted_sections = sort_groups("PnEuMoNiA").sections;
|
||||
assert.deepEqual(sorted_sections.length, 3);
|
||||
assert.deepEqual(sorted_sections[0].streams, []);
|
||||
assert.deepEqual(sorted_sections[1].streams, []);
|
||||
assert.deepEqual(sorted_sections[2].id, "dormant-streams");
|
||||
assert.deepEqual(sorted_sections[2].streams, [pneumonia.stream_id]);
|
||||
|
||||
// Test searching part of word
|
||||
sorted = sort_groups("tortoise");
|
||||
assert.deepEqual(sorted.pinned_streams, []);
|
||||
assert.deepEqual(sorted.normal_streams, [fast_tortoise.stream_id]);
|
||||
assert.deepEqual(sorted.dormant_streams, []);
|
||||
sorted_sections = sort_groups("tortoise").sections;
|
||||
assert.deepEqual(sorted_sections.length, 3);
|
||||
assert.deepEqual(sorted_sections[0].streams, []);
|
||||
assert.deepEqual(sorted_sections[1].id, "normal-streams");
|
||||
assert.deepEqual(sorted_sections[1].streams, [fast_tortoise.stream_id]);
|
||||
assert.deepEqual(sorted_sections[2].streams, []);
|
||||
|
||||
// Test searching stream with spaces
|
||||
sorted = sort_groups("fast t");
|
||||
assert.deepEqual(sorted.pinned_streams, []);
|
||||
assert.deepEqual(sorted.normal_streams, [fast_tortoise.stream_id]);
|
||||
assert.deepEqual(sorted.dormant_streams, []);
|
||||
sorted_sections = sort_groups("fast t").sections;
|
||||
assert.deepEqual(sorted_sections.length, 3);
|
||||
assert.deepEqual(sorted_sections[0].streams, []);
|
||||
assert.deepEqual(sorted_sections[1].id, "normal-streams");
|
||||
assert.deepEqual(sorted_sections[1].streams, [fast_tortoise.stream_id]);
|
||||
assert.deepEqual(sorted_sections[2].streams, []);
|
||||
|
||||
// Test searching part of stream name with non space word separators
|
||||
sorted = sort_groups("hyphen");
|
||||
assert.deepEqual(sorted.pinned_streams, []);
|
||||
assert.deepEqual(sorted.normal_streams, [stream_hyphen_underscore_slash_colon.stream_id]);
|
||||
assert.deepEqual(sorted.dormant_streams, []);
|
||||
sorted_sections = sort_groups("hyphen").sections;
|
||||
assert.deepEqual(sorted_sections.length, 3);
|
||||
assert.deepEqual(sorted_sections[0].streams, []);
|
||||
assert.deepEqual(sorted_sections[1].id, "normal-streams");
|
||||
assert.deepEqual(sorted_sections[1].streams, [stream_hyphen_underscore_slash_colon.stream_id]);
|
||||
assert.deepEqual(sorted_sections[2].streams, []);
|
||||
|
||||
sorted = sort_groups("hyphen_underscore");
|
||||
assert.deepEqual(sorted.pinned_streams, []);
|
||||
assert.deepEqual(sorted.normal_streams, [stream_hyphen_underscore_slash_colon.stream_id]);
|
||||
assert.deepEqual(sorted.dormant_streams, []);
|
||||
sorted_sections = sort_groups("hyphen_underscore").sections;
|
||||
assert.deepEqual(sorted_sections.length, 3);
|
||||
assert.deepEqual(sorted_sections[0].streams, []);
|
||||
assert.deepEqual(sorted_sections[1].id, "normal-streams");
|
||||
assert.deepEqual(sorted_sections[1].streams, [stream_hyphen_underscore_slash_colon.stream_id]);
|
||||
assert.deepEqual(sorted_sections[2].streams, []);
|
||||
|
||||
sorted = sort_groups("colon");
|
||||
assert.deepEqual(sorted.pinned_streams, []);
|
||||
assert.deepEqual(sorted.normal_streams, [stream_hyphen_underscore_slash_colon.stream_id]);
|
||||
assert.deepEqual(sorted.dormant_streams, []);
|
||||
sorted_sections = sort_groups("colon").sections;
|
||||
assert.deepEqual(sorted_sections.length, 3);
|
||||
assert.deepEqual(sorted_sections[0].streams, []);
|
||||
assert.deepEqual(sorted_sections[1].id, "normal-streams");
|
||||
assert.deepEqual(sorted_sections[1].streams, [stream_hyphen_underscore_slash_colon.stream_id]);
|
||||
assert.deepEqual(sorted_sections[2].streams, []);
|
||||
|
||||
sorted = sort_groups("underscore");
|
||||
assert.deepEqual(sorted.pinned_streams, []);
|
||||
assert.deepEqual(sorted.normal_streams, [stream_hyphen_underscore_slash_colon.stream_id]);
|
||||
assert.deepEqual(sorted.dormant_streams, []);
|
||||
sorted_sections = sort_groups("underscore").sections;
|
||||
assert.deepEqual(sorted_sections.length, 3);
|
||||
assert.deepEqual(sorted_sections[0].streams, []);
|
||||
assert.deepEqual(sorted_sections[1].id, "normal-streams");
|
||||
assert.deepEqual(sorted_sections[1].streams, [stream_hyphen_underscore_slash_colon.stream_id]);
|
||||
assert.deepEqual(sorted_sections[2].streams, []);
|
||||
});
|
||||
|
||||
test("filter inactives", ({override}) => {
|
||||
|
||||
Reference in New Issue
Block a user