mirror of
https://github.com/zulip/zulip.git
synced 2025-11-11 17:36:27 +00:00
recent_topics: Display recent topics in a table.
* Add action to mute topics. * We don't need to store muted data per topic as previously planned. * Moved launch topic test to the top so that they run on non-modified data.
This commit is contained in:
@@ -1,13 +1,24 @@
|
||||
const render_recent_topics_body = require('../templates/recent_topics_table.hbs');
|
||||
const render_recent_topic_row = require('../templates/recent_topic_row.hbs');
|
||||
const topics = new Map(); // Key is stream-id:topic.
|
||||
|
||||
exports.process_messages = function (messages) {
|
||||
// Since a complete re-render is expensive, we
|
||||
// only do it if there are more than 5 messages
|
||||
// to process.
|
||||
let do_inplace_rerender = true;
|
||||
if (messages.length > 5) {
|
||||
do_inplace_rerender = false;
|
||||
}
|
||||
for (const msg of messages) {
|
||||
exports.process_message(msg);
|
||||
exports.process_message(msg, do_inplace_rerender);
|
||||
}
|
||||
if (!do_inplace_rerender) {
|
||||
exports.complete_rerender();
|
||||
}
|
||||
};
|
||||
|
||||
exports.process_message = function (msg) {
|
||||
exports.process_message = function (msg, do_inplace_rerender) {
|
||||
if (msg.type !== 'stream') {
|
||||
return false;
|
||||
}
|
||||
@@ -18,7 +29,6 @@ exports.process_message = function (msg) {
|
||||
last_msg_id: -1,
|
||||
starred: new Set(),
|
||||
participated: false,
|
||||
muted: false,
|
||||
});
|
||||
}
|
||||
// Update topic data
|
||||
@@ -31,17 +41,11 @@ exports.process_message = function (msg) {
|
||||
topic_data.starred.add(msg.id);
|
||||
}
|
||||
topic_data.participated = is_ours || topic_data.participated;
|
||||
topic_data.muted = topic_data.muted || muting.is_topic_muted(msg.stream_id, msg.topic);
|
||||
return true;
|
||||
};
|
||||
|
||||
exports.update_topic_is_muted = function (stream_id, topic, is_muted) {
|
||||
const key = stream_id + ":" + topic;
|
||||
if (!topics.has(key)) {
|
||||
return false;
|
||||
if (do_inplace_rerender) {
|
||||
exports.inplace_rerender(key);
|
||||
}
|
||||
const topic_data = topics.get(stream_id + ":" + topic);
|
||||
topic_data.muted = is_muted;
|
||||
return true;
|
||||
};
|
||||
|
||||
function get_sorted_topics() {
|
||||
@@ -68,10 +72,101 @@ exports.process_topic_edit = function (old_stream_id, old_topic, new_topic, new_
|
||||
exports.process_messages(new_topic_msgs);
|
||||
};
|
||||
|
||||
exports.launch = function () {
|
||||
const rendered_body = render_recent_topics_body();
|
||||
$('#recent_topics_table').html(rendered_body);
|
||||
function format_topic(topic_data) {
|
||||
const last_msg = message_store.get(topic_data.last_msg_id);
|
||||
const stream = last_msg.stream;
|
||||
const stream_id = last_msg.stream_id;
|
||||
const topic = last_msg.topic;
|
||||
const time = new XDate(last_msg.timestamp * 1000);
|
||||
const last_msg_time = timerender.last_seen_status_from_date(time);
|
||||
const unread_count = unread.unread_topic_counter.get(stream_id, topic);
|
||||
const hidden = muting.is_topic_muted(stream_id, topic);
|
||||
return {
|
||||
stream_id: stream_id,
|
||||
stream: stream,
|
||||
topic: topic,
|
||||
unread_count: unread_count,
|
||||
last_msg_time: last_msg_time,
|
||||
stream_url: hash_util.by_stream_uri(stream_id),
|
||||
topic_url: hash_util.by_stream_topic_uri(stream_id, topic),
|
||||
hidden: hidden,
|
||||
};
|
||||
}
|
||||
|
||||
function format_all_topics() {
|
||||
const topics_array = [];
|
||||
for (const [, value] of exports.get()) {
|
||||
topics_array.push(format_topic(value));
|
||||
}
|
||||
return topics_array;
|
||||
}
|
||||
|
||||
function get_topic_row(topic_key) {
|
||||
// topic_key = stream_id + ":" + topic
|
||||
return $("#" + $.escapeSelector("recent_topic:" + topic_key));
|
||||
}
|
||||
|
||||
exports.inplace_rerender = function (topic_key) {
|
||||
// We remove topic from the UI and reinsert it.
|
||||
// This makes sure we maintain the correct order
|
||||
// of topics.
|
||||
const topic_data = topics.get(topic_key);
|
||||
if (topic_data === undefined) {
|
||||
return false;
|
||||
}
|
||||
const formatted_values = format_topic(topic_data);
|
||||
const topic_row = get_topic_row(topic_key);
|
||||
topic_row.remove();
|
||||
|
||||
const rendered_row = render_recent_topic_row(formatted_values);
|
||||
|
||||
const sorted_topic_keys = Array.from(get_sorted_topics().keys());
|
||||
const topic_index = sorted_topic_keys.findIndex(
|
||||
function (key) {
|
||||
if (key === topic_key) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
);
|
||||
|
||||
if (topic_index === 0) {
|
||||
// Note: In this function length of sorted_topic_keys is always >= 2,
|
||||
// since it is called after a complete_rerender has taken place.
|
||||
// A complete_rerender only takes place after there is a topic to
|
||||
// display. So, this can at min be the second topic we are dealing with.
|
||||
get_topic_row(sorted_topic_keys[1]).before(rendered_row);
|
||||
}
|
||||
get_topic_row(sorted_topic_keys[topic_index - 1]).after(rendered_row);
|
||||
};
|
||||
|
||||
exports.update_topic_is_muted = function (stream_id, topic, is_muted) {
|
||||
const key = stream_id + ":" + topic;
|
||||
if (!topics.has(key)) {
|
||||
// we receive mute request for a topic we are
|
||||
// not tracking currently
|
||||
return false;
|
||||
}
|
||||
|
||||
if (is_muted) {
|
||||
get_topic_row(key).hide();
|
||||
} else {
|
||||
get_topic_row(key).show();
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
exports.complete_rerender = function () {
|
||||
// NOTE: This function is grows expensive with
|
||||
// number of topics. Only call when necessary.
|
||||
// This functions takes around 1ms per topic to process.
|
||||
const rendered_body = render_recent_topics_body({
|
||||
recent_topics: format_all_topics(),
|
||||
});
|
||||
$('#recent_topics_table').html(rendered_body);
|
||||
};
|
||||
|
||||
exports.launch = function () {
|
||||
overlays.open_overlay({
|
||||
name: 'recent_topics',
|
||||
overlay: $('#recent_topics_overlay'),
|
||||
|
||||
Reference in New Issue
Block a user