mirror of
https://github.com/zulip/zulip.git
synced 2025-11-08 16:01:58 +00:00
topic_list: Move topic filter out of topics list ul.
Instead of topic filter box being a part of the list when keeps updating, we move it out and fix its position. This should reduce rendering time of topics list and provide a smoother experience to users when waiting for topics list to load.
This commit is contained in:
@@ -330,7 +330,7 @@ function elem($obj) {
|
||||
return {to_$: () => $obj};
|
||||
}
|
||||
|
||||
test_ui("zoom_in_and_zoom_out", () => {
|
||||
test_ui("zoom_in_and_zoom_out", ({mock_template}) => {
|
||||
const $label1 = $.create("label1 stub");
|
||||
const $label2 = $.create("label2 stub");
|
||||
|
||||
@@ -376,6 +376,14 @@ test_ui("zoom_in_and_zoom_out", () => {
|
||||
};
|
||||
stream_list.set_event_handlers();
|
||||
|
||||
mock_template("filter_topics", false, () => "filter-topics-stub");
|
||||
let filter_topics_appended = false;
|
||||
$stream_li1.children = () => ({
|
||||
append: (html) => {
|
||||
assert.equal(html, "filter-topics-stub");
|
||||
filter_topics_appended = true;
|
||||
},
|
||||
});
|
||||
stream_list.zoom_in_topics({stream_id: 42});
|
||||
|
||||
assert.ok(!$label1.visible());
|
||||
@@ -384,6 +392,7 @@ test_ui("zoom_in_and_zoom_out", () => {
|
||||
assert.ok($stream_li1.visible());
|
||||
assert.ok(!$stream_li2.visible());
|
||||
assert.ok($("#streams_list").hasClass("zoom-in"));
|
||||
assert.ok(filter_topics_appended);
|
||||
|
||||
$("#stream_filters li.narrow-filter").show = () => {
|
||||
$stream_li1.show();
|
||||
@@ -391,6 +400,9 @@ test_ui("zoom_in_and_zoom_out", () => {
|
||||
};
|
||||
|
||||
$stream_li1.length = 1;
|
||||
$(".filter-topics").remove = () => {
|
||||
filter_topics_appended = false;
|
||||
};
|
||||
stream_list.zoom_out_topics({$stream_li: $stream_li1});
|
||||
|
||||
assert.ok($label1.visible());
|
||||
@@ -399,6 +411,7 @@ test_ui("zoom_in_and_zoom_out", () => {
|
||||
assert.ok($stream_li1.visible());
|
||||
assert.ok($stream_li2.visible());
|
||||
assert.ok($("#streams_list").hasClass("zoom-out"));
|
||||
assert.ok(!filter_topics_appended);
|
||||
});
|
||||
|
||||
test_ui("narrowing", ({mock_template}) => {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import $ from "jquery";
|
||||
import _ from "lodash";
|
||||
|
||||
import render_filter_topics from "../templates/filter_topics.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";
|
||||
@@ -265,6 +266,10 @@ export function zoom_in_topics(options) {
|
||||
|
||||
if (stream_id_for_elt($elt) === stream_id) {
|
||||
$elt.show();
|
||||
// Add search box for topics list.
|
||||
$elt.children("div.bottom_left_row").append(render_filter_topics());
|
||||
$("#filter-topic-input").trigger("focus");
|
||||
$("#clear_search_topic_button").hide();
|
||||
} else {
|
||||
$elt.hide();
|
||||
}
|
||||
@@ -289,6 +294,8 @@ export function zoom_out_topics() {
|
||||
|
||||
$("#streams_list").expectOne().removeClass("zoom-in").addClass("zoom-out");
|
||||
$("#stream_filters li.narrow-filter").show();
|
||||
// Remove search box for topics list from DOM.
|
||||
$(".filter-topics").remove();
|
||||
}
|
||||
|
||||
export function set_in_home_view(stream_id, in_home) {
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import $ from "jquery";
|
||||
import _ from "lodash";
|
||||
|
||||
import render_filter_topics from "../templates/filter_topics.hbs";
|
||||
import render_more_topics from "../templates/more_topics.hbs";
|
||||
import render_more_topics_spinner from "../templates/more_topics_spinner.hbs";
|
||||
import render_topic_list_item from "../templates/topic_list_item.hbs";
|
||||
@@ -117,25 +116,12 @@ export function spinner_li() {
|
||||
};
|
||||
}
|
||||
|
||||
function filter_topics_li() {
|
||||
const eq = (other) => other.filter_topics;
|
||||
|
||||
return {
|
||||
key: "filter",
|
||||
filter_topics: true,
|
||||
render: render_filter_topics,
|
||||
eq,
|
||||
};
|
||||
}
|
||||
|
||||
export class TopicListWidget {
|
||||
prior_dom = undefined;
|
||||
|
||||
constructor($parent_elem, my_stream_id) {
|
||||
this.$parent_elem = $parent_elem;
|
||||
this.my_stream_id = my_stream_id;
|
||||
this.topic_search_text = "";
|
||||
this.topic_search_focused_before_build = true;
|
||||
}
|
||||
|
||||
build_list(spinner) {
|
||||
@@ -158,10 +144,6 @@ export class TopicListWidget {
|
||||
nodes.push(spinner_li());
|
||||
} else if (!is_showing_all_possible_topics) {
|
||||
nodes.push(more_li(more_topics_unreads, more_topics_have_unread_mention_messages));
|
||||
} else if (zoomed) {
|
||||
// In the zoomed topic view, we need to add the input
|
||||
// for filtering through list of topics.
|
||||
nodes.unshift(filter_topics_li());
|
||||
}
|
||||
|
||||
const dom = vdom.ul({
|
||||
@@ -180,50 +162,7 @@ export class TopicListWidget {
|
||||
return this.my_stream_id;
|
||||
}
|
||||
|
||||
update_topic_search_text(text) {
|
||||
this.topic_search_text = text;
|
||||
}
|
||||
|
||||
update_topic_search_input() {
|
||||
const $input = this.$parent_elem.find("#filter-topic-input");
|
||||
if ($input.length) {
|
||||
// Restore topic search text saved in remove()
|
||||
// after the element was rerendered.
|
||||
$input.val(this.topic_search_text);
|
||||
if (this.topic_search_focused_before_build) {
|
||||
// Don't focus topic search if it wasn't focused before.
|
||||
// This avoids unwanted change of focus.
|
||||
$input.trigger("focus");
|
||||
}
|
||||
|
||||
// set up display of clear(x) button.
|
||||
if (this.topic_search_text.length) {
|
||||
$("#clear_search_topic_button").show();
|
||||
} else {
|
||||
$("#clear_search_topic_button").hide();
|
||||
}
|
||||
|
||||
// set up event handlers.
|
||||
const rebuild_list = () => this.build();
|
||||
$input.on("input", rebuild_list);
|
||||
}
|
||||
}
|
||||
|
||||
remove() {
|
||||
// If text was present in the topic search filter, we store
|
||||
// the input value lazily before removing old elements. This
|
||||
// is a workaround for the quirk that the filter input is part
|
||||
// of the region that we rerender.
|
||||
const $input = this.$parent_elem.find("#filter-topic-input");
|
||||
if ($input.length) {
|
||||
this.update_topic_search_text($input.val());
|
||||
// Only set focus on search input if it was focused before the update.
|
||||
this.topic_search_focused_before_build =
|
||||
document.activeElement.id === "filter-topic-input";
|
||||
} else {
|
||||
// Clear the topic search input when zooming out.
|
||||
this.update_topic_search_text("");
|
||||
}
|
||||
this.$parent_elem.find(".topic-list").remove();
|
||||
this.prior_dom = undefined;
|
||||
}
|
||||
@@ -234,7 +173,6 @@ export class TopicListWidget {
|
||||
const replace_content = (html) => {
|
||||
this.remove();
|
||||
this.$parent_elem.append(html);
|
||||
this.update_topic_search_input();
|
||||
};
|
||||
|
||||
const find = () => this.$parent_elem.find(".topic-list");
|
||||
@@ -242,6 +180,12 @@ export class TopicListWidget {
|
||||
vdom.update(replace_content, find, new_dom, this.prior_dom);
|
||||
|
||||
this.prior_dom = new_dom;
|
||||
|
||||
if ($("#filter-topic-input").val() !== "") {
|
||||
$("#clear_search_topic_button").show();
|
||||
} else {
|
||||
$("#clear_search_topic_button").hide();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -374,4 +318,8 @@ export function initialize() {
|
||||
|
||||
e.preventDefault();
|
||||
});
|
||||
|
||||
$("body").on("input", "#filter-topic-input", () => {
|
||||
active_widgets.get(active_stream_id()).build();
|
||||
});
|
||||
}
|
||||
|
||||
@@ -101,6 +101,16 @@ li.show-more-topics {
|
||||
padding: 0;
|
||||
font-weight: normal;
|
||||
|
||||
.input-append.topic_search_section {
|
||||
padding: 2px 0 2px calc($topic_indent - $topic_resolve_width);
|
||||
margin-bottom: 3px;
|
||||
margin-left: 3px;
|
||||
|
||||
input {
|
||||
width: calc(100% - 50px);
|
||||
}
|
||||
}
|
||||
|
||||
li {
|
||||
a {
|
||||
padding: 1px 0;
|
||||
@@ -123,16 +133,6 @@ li.show-more-topics {
|
||||
z-index: 2;
|
||||
background-color: hsl(0, 0%, 100%);
|
||||
}
|
||||
|
||||
.input-append.topic_search_section {
|
||||
margin-bottom: 3px;
|
||||
margin-left: 3px;
|
||||
|
||||
input {
|
||||
padding-right: 20px;
|
||||
width: calc(100% - 50px);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
<li class="topic-list-item filter-topics">
|
||||
<div class="input-append topic_search_section">
|
||||
<div class="input-append topic_search_section filter-topics">
|
||||
<input class="topic-list-filter home-page-input" id="filter-topic-input" type="text" autocomplete="off" placeholder="{{t 'Filter topics'}}" />
|
||||
<button type="button" class="btn clear_search_button" id="clear_search_topic_button">
|
||||
<i class="fa fa-remove" aria-hidden="true"></i>
|
||||
</button>
|
||||
</div>
|
||||
</li>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user