mirror of https://github.com/zulip/zulip.git
muting ui: Update the muted topics table in settings.
The set_up_muted_topics_ui and templates have been refactored to use list_render. This is done to support filtering and sorting of the muted stream topics. This also includes the addition of a new Date muted header.
This commit is contained in:
parent
6983491a0f
commit
3bc818b9f7
|
@ -1,6 +1,9 @@
|
|||
|
||||
zrequire('timerender');
|
||||
zrequire('muting');
|
||||
zrequire('stream_data');
|
||||
set_global('i18n', global.stub_i18n);
|
||||
set_global('XDate', zrequire('XDate', 'xdate'));
|
||||
set_global('page_params', {});
|
||||
|
||||
run_test('edge_cases', () => {
|
||||
|
@ -61,27 +64,49 @@ run_test('basics', () => {
|
|||
|
||||
run_test('get_and_set_muted_topics', () => {
|
||||
assert.deepEqual(muting.get_muted_topics(), []);
|
||||
muting.add_muted_topic(office.stream_id, 'gossip');
|
||||
muting.add_muted_topic(devel.stream_id, 'java');
|
||||
muting.add_muted_topic(office.stream_id, 'gossip', 1577836800);
|
||||
muting.add_muted_topic(devel.stream_id, 'java', 1577836800);
|
||||
assert.deepEqual(muting.get_muted_topics().sort(), [
|
||||
[devel.stream_id, 'java'],
|
||||
[office.stream_id, 'gossip'],
|
||||
]);
|
||||
{
|
||||
date_muted: 1577836800000,
|
||||
date_muted_str: 'Jan 01',
|
||||
stream: devel.name,
|
||||
stream_id: devel.stream_id,
|
||||
topic: 'java',
|
||||
},
|
||||
{
|
||||
date_muted: 1577836800000,
|
||||
date_muted_str: 'Jan 01',
|
||||
stream: office.name,
|
||||
stream_id: office.stream_id,
|
||||
topic: 'gossip',
|
||||
}]);
|
||||
|
||||
blueslip.expect('warn', 'Unknown stream in set_muted_topics: BOGUS STREAM');
|
||||
|
||||
page_params.muted_topics = [
|
||||
['social', 'breakfast'],
|
||||
['design', 'typography'],
|
||||
['BOGUS STREAM', 'whatever'],
|
||||
['social', 'breakfast', 1577836800],
|
||||
['design', 'typography', 1577836800],
|
||||
['BOGUS STREAM', 'whatever', 1577836800],
|
||||
];
|
||||
muting.initialize();
|
||||
|
||||
|
||||
assert.deepEqual(muting.get_muted_topics().sort(), [
|
||||
[design.stream_id, 'typography'],
|
||||
[social.stream_id, 'breakfast'],
|
||||
]);
|
||||
{
|
||||
date_muted: 1577836800000,
|
||||
date_muted_str: 'Jan 01',
|
||||
stream: social.name,
|
||||
stream_id: social.stream_id,
|
||||
topic: 'breakfast',
|
||||
},
|
||||
{
|
||||
date_muted: 1577836800000,
|
||||
date_muted_str: 'Jan 01',
|
||||
stream: design.name,
|
||||
stream_id: design.stream_id,
|
||||
topic: 'typography',
|
||||
}]);
|
||||
});
|
||||
|
||||
run_test('case_insensitivity', () => {
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
set_global('$', global.make_zjquery());
|
||||
set_global('XDate', zrequire('XDate', 'xdate'));
|
||||
|
||||
zrequire('timerender');
|
||||
zrequire('settings_muting');
|
||||
zrequire('stream_data');
|
||||
zrequire('muting');
|
||||
|
@ -15,10 +17,17 @@ stream_data.add_sub(frontend);
|
|||
|
||||
run_test('settings', () => {
|
||||
|
||||
muting.add_muted_topic(frontend.stream_id, 'js');
|
||||
muting.add_muted_topic(frontend.stream_id, 'js', 1577836800);
|
||||
let set_up_ui_called = false;
|
||||
muting_ui.set_up_muted_topics_ui = function (opts) {
|
||||
assert.deepEqual(opts, [[frontend.stream_id, 'js']]);
|
||||
assert.deepEqual(opts, [
|
||||
{
|
||||
date_muted: 1577836800000,
|
||||
date_muted_str: 'Jan 01',
|
||||
stream: frontend.name,
|
||||
stream_id: frontend.stream_id,
|
||||
topic: 'js',
|
||||
}]);
|
||||
set_up_ui_called = true;
|
||||
};
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
|
||||
zrequire('timerender');
|
||||
zrequire('muting');
|
||||
zrequire('people');
|
||||
zrequire('stream_data');
|
||||
|
@ -11,6 +12,9 @@ zrequire('settings_notifications');
|
|||
|
||||
const FoldDict = zrequire('fold_dict').FoldDict;
|
||||
|
||||
set_global('i18n', global.stub_i18n);
|
||||
set_global('XDate', zrequire('XDate', 'xdate'));
|
||||
set_global('page_params', {});
|
||||
set_global('narrow_state', {});
|
||||
set_global('current_msg_list', {});
|
||||
set_global('home_msg_list', {});
|
||||
|
|
|
@ -2,13 +2,17 @@ const FoldDict = require('./fold_dict').FoldDict;
|
|||
|
||||
const muted_topics = new Map();
|
||||
|
||||
exports.add_muted_topic = function (stream_id, topic) {
|
||||
exports.add_muted_topic = function (stream_id, topic, date_muted) {
|
||||
let sub_dict = muted_topics.get(stream_id);
|
||||
if (!sub_dict) {
|
||||
sub_dict = new FoldDict();
|
||||
muted_topics.set(stream_id, sub_dict);
|
||||
}
|
||||
sub_dict.set(topic, true);
|
||||
let time = date_muted * 1000;
|
||||
if (!date_muted) {
|
||||
time = Date.now();
|
||||
}
|
||||
sub_dict.set(topic, time);
|
||||
};
|
||||
|
||||
exports.remove_muted_topic = function (stream_id, topic) {
|
||||
|
@ -29,8 +33,17 @@ exports.is_topic_muted = function (stream_id, topic) {
|
|||
exports.get_muted_topics = function () {
|
||||
const topics = [];
|
||||
for (const [stream_id, sub_dict] of muted_topics) {
|
||||
const stream = stream_data.maybe_get_stream_name(stream_id);
|
||||
for (const topic of sub_dict.keys()) {
|
||||
topics.push([stream_id, topic]);
|
||||
const date_muted = sub_dict.get(topic);
|
||||
const date_muted_str = timerender.render_now(new XDate(date_muted)).time_str;
|
||||
topics.push({
|
||||
stream_id: stream_id,
|
||||
stream: stream,
|
||||
topic: topic,
|
||||
date_muted: date_muted,
|
||||
date_muted_str: date_muted_str,
|
||||
});
|
||||
}
|
||||
}
|
||||
return topics;
|
||||
|
@ -42,6 +55,7 @@ exports.set_muted_topics = function (tuples) {
|
|||
for (const tuple of tuples) {
|
||||
const stream_name = tuple[0];
|
||||
const topic = tuple[1];
|
||||
const date_muted = tuple[2];
|
||||
|
||||
const stream_id = stream_data.get_stream_id(stream_name);
|
||||
|
||||
|
@ -50,7 +64,7 @@ exports.set_muted_topics = function (tuples) {
|
|||
continue;
|
||||
}
|
||||
|
||||
exports.add_muted_topic(stream_id, topic);
|
||||
exports.add_muted_topic(stream_id, topic, date_muted);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -68,29 +68,25 @@ exports.update_muted_topics = function (muted_topics) {
|
|||
};
|
||||
|
||||
exports.set_up_muted_topics_ui = function (muted_topics) {
|
||||
const muted_topics_table = $("#muted_topics_table tbody");
|
||||
muted_topics_table.empty();
|
||||
const muted_topics_table = $("#muted_topics_table").expectOne();
|
||||
const $search_input = $("#muted_topics_search");
|
||||
|
||||
for (const tup of muted_topics) {
|
||||
const stream_id = tup[0];
|
||||
const topic = tup[1];
|
||||
|
||||
const stream = stream_data.maybe_get_stream_name(stream_id);
|
||||
|
||||
if (!stream) {
|
||||
blueslip.warn('Unknown stream_id in set_up_muted_topics_ui: ' + stream_id);
|
||||
continue;
|
||||
}
|
||||
|
||||
const template_data = {
|
||||
stream: stream,
|
||||
stream_id: stream_id,
|
||||
topic: topic,
|
||||
};
|
||||
|
||||
const row = render_muted_topic_ui_row(template_data);
|
||||
muted_topics_table.append(row);
|
||||
}
|
||||
list_render.create(muted_topics_table, muted_topics, {
|
||||
name: "muted-topics-list",
|
||||
modifier: function (muted_topics) {
|
||||
return render_muted_topic_ui_row({ muted_topics: muted_topics });
|
||||
},
|
||||
filter: {
|
||||
element: $search_input,
|
||||
predicate: function (item, value) {
|
||||
return item.topic.toLocaleLowerCase().indexOf(value) >= 0;
|
||||
},
|
||||
onupdate: function () {
|
||||
ui.reset_scrollbar(muted_topics_table.closest(".progressive-table-wrapper"));
|
||||
},
|
||||
},
|
||||
parent_container: $('#muted-topic-settings').expectOne(),
|
||||
});
|
||||
};
|
||||
|
||||
exports.mute = function (stream_id, topic) {
|
||||
|
@ -114,7 +110,6 @@ exports.mute = function (stream_id, topic) {
|
|||
title_text: i18n.t("Topic muted"),
|
||||
undo_button_text: i18n.t("Unmute"),
|
||||
});
|
||||
exports.set_up_muted_topics_ui(muting.get_muted_topics());
|
||||
};
|
||||
|
||||
exports.unmute = function (stream_id, topic) {
|
||||
|
@ -126,7 +121,6 @@ exports.unmute = function (stream_id, topic) {
|
|||
unread_ui.update_unread_counts();
|
||||
exports.rerender();
|
||||
exports.persist_unmute(stream_id, topic);
|
||||
exports.set_up_muted_topics_ui(muting.get_muted_topics());
|
||||
feedback_widget.dismiss();
|
||||
};
|
||||
|
||||
|
|
|
@ -1,5 +1,10 @@
|
|||
<tr data-stream-id="{{stream_id}}" data-topic="{{topic}}">
|
||||
{{#with muted_topics}}
|
||||
<tr data-stream-id={{stream_id}} data-stream="{{stream}}" data-topic="{{topic}}" data-date-muted="{{date_muted_str}}">
|
||||
<td>{{stream}}</td>
|
||||
<td>{{topic}}</td>
|
||||
<td><a class="settings-unmute-topic">Unmute</a></td>
|
||||
<td>{{date_muted_str}}</td>
|
||||
<td class="actions">
|
||||
<span><a class="settings-unmute-topic">Unmute</a></span>
|
||||
</td>
|
||||
</tr>
|
||||
{{/with}}
|
||||
|
|
|
@ -1,10 +1,14 @@
|
|||
<div id="muted-topic-settings" class="settings-section" data-name="muted-topics">
|
||||
<table id="muted_topics_table" class="table">
|
||||
<input id="muted_topics_search" class="search" type="text" placeholder="{{t 'Search muted topics...' }}" aria-label="{{t 'Search muted topics...' }}"/>
|
||||
<div class="progressive-table-wrapper" data-simplebar data-list-render="muted-topics-list">
|
||||
<table class="table table-condensed table-striped wrapped-table">
|
||||
<thead>
|
||||
<th>{{t "Stream" }}</th>
|
||||
<th>{{t "Topic" }}</th>
|
||||
<th data-sort="alphabetic" data-sort-prop="stream">{{t "Stream" }}</th>
|
||||
<th data-sort="alphabetic" data-sort-prop="topic">{{t "Topic" }}</th>
|
||||
<th data-sort="numeric" data-sort-prop="date_muted">{{t "Date muted" }}</th>
|
||||
<th class="actions">{{t "Actions" }}</th>
|
||||
</thead>
|
||||
<tbody class="required-text" data-empty="{{t 'You have not muted any topics yet.'}}"></tbody>
|
||||
<tbody id="muted_topics_table" data-empty="{{t 'You have not muted any topics yet.'}}" data-list-render="muted-topics-list"></tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
|
Loading…
Reference in New Issue