mirror of https://github.com/zulip/zulip.git
user_settings: Add option to only read messages on scroll in topic.
After merging #24309, we want to add an additional option to the "mark messages as read on scroll" setting where we only mark messages as read on scroll in conversation views.
This commit is contained in:
parent
596abf6190
commit
e999518d9a
|
@ -1101,4 +1101,12 @@ export class Filter {
|
|||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
is_conversation_view() {
|
||||
const term_type = this.sorted_term_types();
|
||||
if (_.isEqual(term_type, ["stream", "topic"]) || _.isEqual(term_type, ["pm-with"])) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -184,12 +184,19 @@ export class MessageList {
|
|||
* The user has "Mark messages as read on scroll" option
|
||||
turned on in their user settings.
|
||||
*/
|
||||
const filter = this.data.filter;
|
||||
const is_conversation_view = filter === undefined ? false : filter.is_conversation_view();
|
||||
return (
|
||||
this.data.can_mark_messages_read() &&
|
||||
!this.reading_prevented &&
|
||||
!(
|
||||
user_settings.web_mark_read_on_scroll_policy ===
|
||||
web_mark_read_on_scroll_policy_values.never.code
|
||||
) &&
|
||||
!(
|
||||
user_settings.web_mark_read_on_scroll_policy ===
|
||||
web_mark_read_on_scroll_policy_values.conversation_only.code &&
|
||||
!is_conversation_view
|
||||
)
|
||||
);
|
||||
}
|
||||
|
|
|
@ -594,6 +594,7 @@ export function activate(raw_operators, opts) {
|
|||
stream_list.handle_narrow_activated(current_filter);
|
||||
typing_events.render_notifications_for_narrow();
|
||||
message_view_header.initialize();
|
||||
unread_ui.update_unread_banner();
|
||||
|
||||
// It is important to call this after other important updates
|
||||
// like narrow filter and compose recipients happen.
|
||||
|
|
|
@ -44,11 +44,10 @@ export const web_mark_read_on_scroll_policy_values = {
|
|||
code: 1,
|
||||
description: $t({defaultMessage: "Always"}),
|
||||
},
|
||||
// The `conversation_only` option is not yet implemented.
|
||||
// conversation_only: {
|
||||
// code: 2,
|
||||
// description: $t({defaultMessage: "Only in conversation views"}),
|
||||
// },
|
||||
conversation_only: {
|
||||
code: 2,
|
||||
description: $t({defaultMessage: "Only in conversation views"}),
|
||||
},
|
||||
never: {
|
||||
code: 3,
|
||||
description: $t({defaultMessage: "Never"}),
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
import $ from "jquery";
|
||||
|
||||
import render_mark_as_read_disabled_banner from "../templates/mark_as_read_disabled_banner.hbs";
|
||||
import render_mark_as_read_only_in_conversation_view from "../templates/mark_as_read_only_in_conversation_view.hbs";
|
||||
import render_mark_as_read_turned_off_banner from "../templates/mark_as_read_turned_off_banner.hbs";
|
||||
|
||||
import * as activity from "./activity";
|
||||
import * as message_lists from "./message_lists";
|
||||
import * as narrow_state from "./narrow_state";
|
||||
import * as notifications from "./notifications";
|
||||
import {page_params} from "./page_params";
|
||||
import * as pm_list from "./pm_list";
|
||||
|
@ -19,11 +21,19 @@ import {user_settings} from "./user_settings";
|
|||
let user_closed_unread_banner = false;
|
||||
|
||||
export function update_unread_banner() {
|
||||
const filter = narrow_state.filter();
|
||||
const is_conversation_view = filter === undefined ? false : filter.is_conversation_view();
|
||||
if (
|
||||
user_settings.web_mark_read_on_scroll_policy ===
|
||||
web_mark_read_on_scroll_policy_values.never.code
|
||||
) {
|
||||
$("#mark_as_read_turned_off_banner").html(render_mark_as_read_disabled_banner());
|
||||
} else if (
|
||||
user_settings.web_mark_read_on_scroll_policy ===
|
||||
web_mark_read_on_scroll_policy_values.conversation_only.code &&
|
||||
!is_conversation_view
|
||||
) {
|
||||
$("#mark_as_read_turned_off_banner").html(render_mark_as_read_only_in_conversation_view());
|
||||
} else {
|
||||
$("#mark_as_read_turned_off_banner").html(render_mark_as_read_turned_off_banner());
|
||||
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
<p id="mark_as_read_turned_off_content">
|
||||
{{#tr}}
|
||||
Your Zulip app is <z-link>configured</z-link> to mark messages as read on scroll only in conversation views.
|
||||
{{#*inline "z-link"}}<a href='help/marking-messages-as-read'>{{> @partial-block}}</a>{{/inline}}
|
||||
{{/tr}}
|
||||
</p>
|
||||
<div id="mark_as_read_controls">
|
||||
<button id="mark_view_read" class="btn btn-warning">
|
||||
{{t 'Mark as read' }}
|
||||
</button>
|
||||
</div>
|
||||
<button type="button" id="mark_as_read_close" class="close">×</button>
|
|
@ -96,6 +96,7 @@ test("basics", () => {
|
|||
assert.ok(filter.includes_full_stream_history());
|
||||
assert.ok(filter.can_apply_locally());
|
||||
assert.ok(!filter.is_personal_filter());
|
||||
assert.ok(!filter.is_conversation_view());
|
||||
|
||||
operators = [
|
||||
{operator: "stream", operand: "foo"},
|
||||
|
@ -113,6 +114,7 @@ test("basics", () => {
|
|||
assert.ok(!filter.is_personal_filter());
|
||||
assert.ok(filter.can_bucket_by("stream"));
|
||||
assert.ok(filter.can_bucket_by("stream", "topic"));
|
||||
assert.ok(!filter.is_conversation_view());
|
||||
|
||||
operators = [
|
||||
{operator: "stream", operand: "foo"},
|
||||
|
@ -130,6 +132,7 @@ test("basics", () => {
|
|||
assert.ok(!filter.is_personal_filter());
|
||||
assert.ok(filter.can_bucket_by("stream"));
|
||||
assert.ok(filter.can_bucket_by("stream", "topic"));
|
||||
assert.ok(!filter.is_conversation_view());
|
||||
|
||||
// If our only stream operator is negated, then for all intents and purposes,
|
||||
// we don't consider ourselves to have a stream operator, because we don't
|
||||
|
@ -141,6 +144,7 @@ test("basics", () => {
|
|||
assert.ok(!filter.can_mark_messages_read());
|
||||
assert.ok(filter.supports_collapsing_recipients());
|
||||
assert.ok(!filter.is_personal_filter());
|
||||
assert.ok(!filter.is_conversation_view());
|
||||
|
||||
// Negated searches are just like positive searches for our purposes, since
|
||||
// the search logic happens on the backend and we need to have can_apply_locally()
|
||||
|
@ -153,6 +157,7 @@ test("basics", () => {
|
|||
assert.ok(!filter.can_mark_messages_read());
|
||||
assert.ok(!filter.supports_collapsing_recipients());
|
||||
assert.ok(!filter.is_personal_filter());
|
||||
assert.ok(!filter.is_conversation_view());
|
||||
|
||||
// Similar logic applies to negated "has" searches.
|
||||
operators = [{operator: "has", operand: "images", negated: true}];
|
||||
|
@ -164,6 +169,7 @@ test("basics", () => {
|
|||
assert.ok(!filter.can_mark_messages_read());
|
||||
assert.ok(!filter.supports_collapsing_recipients());
|
||||
assert.ok(!filter.is_personal_filter());
|
||||
assert.ok(!filter.is_conversation_view());
|
||||
|
||||
operators = [{operator: "streams", operand: "public", negated: true}];
|
||||
filter = new Filter(operators);
|
||||
|
@ -174,6 +180,7 @@ test("basics", () => {
|
|||
assert.ok(filter.has_negated_operand("streams", "public"));
|
||||
assert.ok(!filter.can_apply_locally());
|
||||
assert.ok(!filter.is_personal_filter());
|
||||
assert.ok(!filter.is_conversation_view());
|
||||
|
||||
operators = [{operator: "streams", operand: "public"}];
|
||||
filter = new Filter(operators);
|
||||
|
@ -185,6 +192,7 @@ test("basics", () => {
|
|||
assert.ok(!filter.can_apply_locally());
|
||||
assert.ok(filter.includes_full_stream_history());
|
||||
assert.ok(!filter.is_personal_filter());
|
||||
assert.ok(!filter.is_conversation_view());
|
||||
|
||||
operators = [{operator: "is", operand: "private"}];
|
||||
filter = new Filter(operators);
|
||||
|
@ -194,6 +202,7 @@ test("basics", () => {
|
|||
assert.ok(!filter.has_operator("search"));
|
||||
assert.ok(filter.can_apply_locally());
|
||||
assert.ok(!filter.is_personal_filter());
|
||||
assert.ok(!filter.is_conversation_view());
|
||||
|
||||
operators = [{operator: "is", operand: "mentioned"}];
|
||||
filter = new Filter(operators);
|
||||
|
@ -203,6 +212,7 @@ test("basics", () => {
|
|||
assert.ok(!filter.has_operator("search"));
|
||||
assert.ok(filter.can_apply_locally());
|
||||
assert.ok(filter.is_personal_filter());
|
||||
assert.ok(!filter.is_conversation_view());
|
||||
|
||||
operators = [{operator: "is", operand: "starred"}];
|
||||
filter = new Filter(operators);
|
||||
|
@ -212,6 +222,7 @@ test("basics", () => {
|
|||
assert.ok(!filter.has_operator("search"));
|
||||
assert.ok(filter.can_apply_locally());
|
||||
assert.ok(filter.is_personal_filter());
|
||||
assert.ok(!filter.is_conversation_view());
|
||||
|
||||
operators = [{operator: "pm-with", operand: "joe@example.com"}];
|
||||
filter = new Filter(operators);
|
||||
|
@ -222,6 +233,7 @@ test("basics", () => {
|
|||
assert.ok(!filter.has_operator("search"));
|
||||
assert.ok(filter.can_apply_locally());
|
||||
assert.ok(!filter.is_personal_filter());
|
||||
assert.ok(filter.is_conversation_view());
|
||||
|
||||
operators = [{operator: "pm-with", operand: "joe@example.com,jack@example.com"}];
|
||||
filter = new Filter(operators);
|
||||
|
@ -231,6 +243,7 @@ test("basics", () => {
|
|||
assert.ok(filter.supports_collapsing_recipients());
|
||||
assert.ok(filter.can_apply_locally());
|
||||
assert.ok(!filter.is_personal_filter());
|
||||
assert.ok(filter.is_conversation_view());
|
||||
|
||||
operators = [{operator: "group-pm-with", operand: "joe@example.com"}];
|
||||
filter = new Filter(operators);
|
||||
|
@ -241,6 +254,7 @@ test("basics", () => {
|
|||
assert.ok(filter.supports_collapsing_recipients());
|
||||
assert.ok(filter.can_apply_locally());
|
||||
assert.ok(!filter.is_personal_filter());
|
||||
assert.ok(!filter.is_conversation_view());
|
||||
|
||||
operators = [{operator: "is", operand: "resolved"}];
|
||||
filter = new Filter(operators);
|
||||
|
@ -250,6 +264,7 @@ test("basics", () => {
|
|||
assert.ok(filter.supports_collapsing_recipients());
|
||||
assert.ok(filter.can_apply_locally());
|
||||
assert.ok(!filter.is_personal_filter());
|
||||
assert.ok(!filter.is_conversation_view());
|
||||
|
||||
// Highly complex query to exercise
|
||||
// filter.supports_collapsing_recipients loop.
|
||||
|
@ -271,6 +286,23 @@ test("basics", () => {
|
|||
// comment in the can_apply_locally implementation.
|
||||
assert.ok(!filter.can_apply_locally());
|
||||
assert.ok(!filter.is_personal_filter());
|
||||
assert.ok(!filter.is_conversation_view());
|
||||
|
||||
operators = [
|
||||
{operator: "stream", operand: "foo"},
|
||||
{operator: "topic", operand: "bar"},
|
||||
];
|
||||
filter = new Filter(operators);
|
||||
|
||||
assert.ok(!filter.is_search());
|
||||
assert.ok(filter.can_mark_messages_read());
|
||||
assert.ok(filter.supports_collapsing_recipients());
|
||||
assert.ok(!filter.contains_only_private_messages());
|
||||
assert.ok(filter.allow_use_first_unread_when_narrowing());
|
||||
assert.ok(filter.includes_full_stream_history());
|
||||
assert.ok(filter.can_apply_locally());
|
||||
assert.ok(!filter.is_personal_filter());
|
||||
assert.ok(filter.is_conversation_view());
|
||||
});
|
||||
|
||||
function assert_not_mark_read_with_has_operands(additional_operators_to_test) {
|
||||
|
|
|
@ -39,6 +39,10 @@ mock_esm("../src/recent_topics_util", {
|
|||
mock_esm("../src/pm_list", {
|
||||
handle_narrow_activated() {},
|
||||
});
|
||||
mock_esm("../src/unread_ui", {
|
||||
reset_unread_banner() {},
|
||||
update_unread_banner() {},
|
||||
});
|
||||
|
||||
//
|
||||
// We have strange hacks in narrow.activate to sleep 0
|
||||
|
|
Loading…
Reference in New Issue