mirror of
https://github.com/zulip/zulip.git
synced 2025-11-14 19:06:09 +00:00
compose: Handle fading with general chat.
This commit also attempts to fix a bug, present in main, where a draft restored directly to the compose box loses its original topic upon switching to other topic narrows. Co-authored-by: Prakhar Pratyush <prakhar@zulip.com>
This commit is contained in:
@@ -26,6 +26,7 @@ import * as reload_state from "./reload_state.ts";
|
|||||||
import * as resize from "./resize.ts";
|
import * as resize from "./resize.ts";
|
||||||
import * as saved_snippets_ui from "./saved_snippets_ui.ts";
|
import * as saved_snippets_ui from "./saved_snippets_ui.ts";
|
||||||
import * as spectators from "./spectators.ts";
|
import * as spectators from "./spectators.ts";
|
||||||
|
import {realm} from "./state_data.ts";
|
||||||
import * as stream_data from "./stream_data.ts";
|
import * as stream_data from "./stream_data.ts";
|
||||||
|
|
||||||
// Opts sent to `compose_actions.start`.
|
// Opts sent to `compose_actions.start`.
|
||||||
@@ -516,7 +517,8 @@ export let on_topic_narrow = (): void => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (
|
if (
|
||||||
(compose_state.topic() && compose_state.has_novel_message_content()) ||
|
((compose_state.topic() || !realm.realm_mandatory_topics) &&
|
||||||
|
compose_state.has_message_content()) ||
|
||||||
compose_state.is_recipient_edited_manually()
|
compose_state.is_recipient_edited_manually()
|
||||||
) {
|
) {
|
||||||
// If the user has written something to a different topic or edited it,
|
// If the user has written something to a different topic or edited it,
|
||||||
|
|||||||
@@ -105,7 +105,7 @@ function fade_messages(): void {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function do_update_all(): void {
|
export function do_update_all(): void {
|
||||||
if (compose_fade_helper.want_normal_display()) {
|
if (compose_fade_helper.want_normal_display()) {
|
||||||
if (!normal_display) {
|
if (!normal_display) {
|
||||||
display_messages_normally();
|
display_messages_normally();
|
||||||
|
|||||||
@@ -1,4 +1,7 @@
|
|||||||
|
import $ from "jquery";
|
||||||
|
|
||||||
import type {Message} from "./message_store.ts";
|
import type {Message} from "./message_store.ts";
|
||||||
|
import {realm} from "./state_data.ts";
|
||||||
import * as sub_store from "./sub_store.ts";
|
import * as sub_store from "./sub_store.ts";
|
||||||
import type {Recipient} from "./util.ts";
|
import type {Recipient} from "./util.ts";
|
||||||
import * as util from "./util.ts";
|
import * as util from "./util.ts";
|
||||||
@@ -31,11 +34,14 @@ export function want_normal_display(): boolean {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is kind of debatable. If the topic is empty, it could be that
|
// If the topic is empty, we want a normal display in the following cases:
|
||||||
// the user simply hasn't started typing it yet, but disabling fading here
|
// * realm requires topic
|
||||||
// means the feature doesn't help realms where topics aren't mandatory
|
// * realm allows empty topic but the focus is in topic input box,
|
||||||
// (which is most realms as of this writing).
|
// means user is still configuring topic.
|
||||||
if (focused_recipient.topic === "") {
|
if (
|
||||||
|
focused_recipient.topic === "" &&
|
||||||
|
(realm.realm_mandatory_topics || $("input#stream_message_recipient_topic").is(":focus"))
|
||||||
|
) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import * as compose_actions from "./compose_actions.ts";
|
|||||||
import * as compose_banner from "./compose_banner.ts";
|
import * as compose_banner from "./compose_banner.ts";
|
||||||
import * as compose_call from "./compose_call.ts";
|
import * as compose_call from "./compose_call.ts";
|
||||||
import * as compose_call_ui from "./compose_call_ui.ts";
|
import * as compose_call_ui from "./compose_call_ui.ts";
|
||||||
|
import * as compose_fade from "./compose_fade.ts";
|
||||||
import * as compose_notifications from "./compose_notifications.ts";
|
import * as compose_notifications from "./compose_notifications.ts";
|
||||||
import * as compose_recipient from "./compose_recipient.ts";
|
import * as compose_recipient from "./compose_recipient.ts";
|
||||||
import * as compose_send_menu_popover from "./compose_send_menu_popover.js";
|
import * as compose_send_menu_popover from "./compose_send_menu_popover.js";
|
||||||
@@ -583,6 +584,7 @@ export function initialize() {
|
|||||||
|
|
||||||
$("textarea#compose-textarea").on("focus", () => {
|
$("textarea#compose-textarea").on("focus", () => {
|
||||||
compose_recipient.update_compose_area_placeholder_text();
|
compose_recipient.update_compose_area_placeholder_text();
|
||||||
|
compose_fade.do_update_all();
|
||||||
if (narrow_state.narrowed_by_reply()) {
|
if (narrow_state.narrowed_by_reply()) {
|
||||||
compose_notifications.maybe_show_one_time_non_interleaved_view_messages_fading_banner();
|
compose_notifications.maybe_show_one_time_non_interleaved_view_messages_fading_banner();
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import $ from "jquery";
|
|||||||
|
|
||||||
import * as compose_pm_pill from "./compose_pm_pill.ts";
|
import * as compose_pm_pill from "./compose_pm_pill.ts";
|
||||||
import * as people from "./people.ts";
|
import * as people from "./people.ts";
|
||||||
|
import {realm} from "./state_data.ts";
|
||||||
import * as sub_store from "./sub_store.ts";
|
import * as sub_store from "./sub_store.ts";
|
||||||
|
|
||||||
let message_type: "stream" | "private" | undefined;
|
let message_type: "stream" | "private" | undefined;
|
||||||
@@ -231,7 +232,8 @@ export function has_savable_message_content(): boolean {
|
|||||||
|
|
||||||
export function has_full_recipient(): boolean {
|
export function has_full_recipient(): boolean {
|
||||||
if (message_type === "stream") {
|
if (message_type === "stream") {
|
||||||
return stream_id() !== undefined && topic() !== "";
|
const has_topic = topic() !== "" || !realm.realm_mandatory_topics;
|
||||||
|
return stream_id() !== undefined && has_topic;
|
||||||
}
|
}
|
||||||
return private_message_recipient() !== "";
|
return private_message_recipient() !== "";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1378,7 +1378,7 @@ export function to_compose_target(): void {
|
|||||||
// grey-out the message view instead of narrowing to an empty view.
|
// grey-out the message view instead of narrowing to an empty view.
|
||||||
const terms = [{operator: "channel", operand: stream_id.toString()}];
|
const terms = [{operator: "channel", operand: stream_id.toString()}];
|
||||||
const topic = compose_state.topic();
|
const topic = compose_state.topic();
|
||||||
if (topic !== "") {
|
if (topic !== "" || !realm.realm_mandatory_topics) {
|
||||||
terms.push({operator: "topic", operand: topic});
|
terms.push({operator: "topic", operand: topic});
|
||||||
}
|
}
|
||||||
show(terms, opts);
|
show(terms, opts);
|
||||||
|
|||||||
@@ -823,6 +823,7 @@ test_ui("on_events", ({override, override_rewire}) => {
|
|||||||
fake_compose_box.show_message_preview();
|
fake_compose_box.show_message_preview();
|
||||||
|
|
||||||
override_rewire(compose_recipient, "update_compose_area_placeholder_text", noop);
|
override_rewire(compose_recipient, "update_compose_area_placeholder_text", noop);
|
||||||
|
override(compose_fade, "do_update_all", noop);
|
||||||
override(narrow_state, "narrowed_by_reply", () => true);
|
override(narrow_state, "narrowed_by_reply", () => true);
|
||||||
override(
|
override(
|
||||||
compose_notifications,
|
compose_notifications,
|
||||||
|
|||||||
@@ -12,6 +12,15 @@ mock_jquery((selector) => {
|
|||||||
val() {
|
val() {
|
||||||
return "lunch";
|
return "lunch";
|
||||||
},
|
},
|
||||||
|
is(arg) {
|
||||||
|
switch (arg) {
|
||||||
|
case ":focus":
|
||||||
|
return true;
|
||||||
|
/* istanbul ignore next */
|
||||||
|
default:
|
||||||
|
throw new Error(`Unknown arg ${arg}`);
|
||||||
|
}
|
||||||
|
},
|
||||||
};
|
};
|
||||||
/* istanbul ignore next */
|
/* istanbul ignore next */
|
||||||
default:
|
default:
|
||||||
@@ -25,6 +34,10 @@ const people = zrequire("people");
|
|||||||
const compose_fade = zrequire("compose_fade");
|
const compose_fade = zrequire("compose_fade");
|
||||||
const compose_fade_helper = zrequire("compose_fade_helper");
|
const compose_fade_helper = zrequire("compose_fade_helper");
|
||||||
const compose_state = zrequire("compose_state");
|
const compose_state = zrequire("compose_state");
|
||||||
|
const {set_realm} = zrequire("state_data");
|
||||||
|
|
||||||
|
const realm = {};
|
||||||
|
set_realm(realm);
|
||||||
|
|
||||||
const me = {
|
const me = {
|
||||||
email: "me@example.com",
|
email: "me@example.com",
|
||||||
@@ -77,7 +90,7 @@ run_test("set_focused_recipient", () => {
|
|||||||
assert.ok(compose_fade_helper.should_fade_message(bad_msg));
|
assert.ok(compose_fade_helper.should_fade_message(bad_msg));
|
||||||
});
|
});
|
||||||
|
|
||||||
run_test("want_normal_display", () => {
|
run_test("want_normal_display", ({override}) => {
|
||||||
const stream_id = 110;
|
const stream_id = 110;
|
||||||
const sub = {
|
const sub = {
|
||||||
stream_id,
|
stream_id,
|
||||||
@@ -100,9 +113,16 @@ run_test("want_normal_display", () => {
|
|||||||
assert.ok(compose_fade_helper.want_normal_display());
|
assert.ok(compose_fade_helper.want_normal_display());
|
||||||
|
|
||||||
// Focused recipient is a valid stream with no topic set
|
// Focused recipient is a valid stream with no topic set
|
||||||
|
// when topics are mandatory
|
||||||
|
override(realm, "realm_mandatory_topics", true);
|
||||||
stream_data.add_sub(sub);
|
stream_data.add_sub(sub);
|
||||||
assert.ok(compose_fade_helper.want_normal_display());
|
assert.ok(compose_fade_helper.want_normal_display());
|
||||||
|
|
||||||
|
// Focused recipient is a valid stream with no topic set
|
||||||
|
// when topics are not mandatory. Focused to input box.
|
||||||
|
override(realm, "realm_mandatory_topics", false);
|
||||||
|
assert.ok(compose_fade_helper.want_normal_display());
|
||||||
|
|
||||||
// If we're focused to a topic, then we do want to fade.
|
// If we're focused to a topic, then we do want to fade.
|
||||||
compose_fade_helper.set_focused_recipient({
|
compose_fade_helper.set_focused_recipient({
|
||||||
type: "stream",
|
type: "stream",
|
||||||
|
|||||||
@@ -10,6 +10,10 @@ const compose_pm_pill = mock_esm("../src/compose_pm_pill");
|
|||||||
|
|
||||||
const compose_state = zrequire("compose_state");
|
const compose_state = zrequire("compose_state");
|
||||||
const stream_data = zrequire("stream_data");
|
const stream_data = zrequire("stream_data");
|
||||||
|
const {set_realm} = zrequire("state_data");
|
||||||
|
|
||||||
|
const realm = {};
|
||||||
|
set_realm(realm);
|
||||||
|
|
||||||
run_test("private_message_recipient", ({override}) => {
|
run_test("private_message_recipient", ({override}) => {
|
||||||
let emails;
|
let emails;
|
||||||
|
|||||||
@@ -769,7 +769,7 @@ run_test("narrow_to_compose_target errors", ({disallow_rewire}) => {
|
|||||||
message_view.to_compose_target();
|
message_view.to_compose_target();
|
||||||
});
|
});
|
||||||
|
|
||||||
run_test("narrow_to_compose_target streams", ({override_rewire}) => {
|
run_test("narrow_to_compose_target streams", ({override, override_rewire}) => {
|
||||||
const args = {called: false};
|
const args = {called: false};
|
||||||
override_rewire(message_view, "show", (terms, opts) => {
|
override_rewire(message_view, "show", (terms, opts) => {
|
||||||
args.terms = terms;
|
args.terms = terms;
|
||||||
@@ -803,19 +803,43 @@ run_test("narrow_to_compose_target streams", ({override_rewire}) => {
|
|||||||
{operator: "topic", operand: "four"},
|
{operator: "topic", operand: "four"},
|
||||||
]);
|
]);
|
||||||
|
|
||||||
// Test with blank topic
|
// Test with blank topic, with realm_mandatory_topics
|
||||||
|
override(realm, "realm_mandatory_topics", true);
|
||||||
compose_state.topic("");
|
compose_state.topic("");
|
||||||
args.called = false;
|
args.called = false;
|
||||||
message_view.to_compose_target();
|
message_view.to_compose_target();
|
||||||
assert.equal(args.called, true);
|
assert.equal(args.called, true);
|
||||||
assert.deepEqual(args.terms, [{operator: "channel", operand: rome_id.toString()}]);
|
assert.deepEqual(args.terms, [{operator: "channel", operand: rome_id.toString()}]);
|
||||||
|
|
||||||
// Test with no topic
|
// Test with blank topic, without realm_mandatory_topics
|
||||||
|
override(realm, "realm_mandatory_topics", false);
|
||||||
|
compose_state.topic("");
|
||||||
|
args.called = false;
|
||||||
|
message_view.to_compose_target();
|
||||||
|
assert.equal(args.called, true);
|
||||||
|
assert.deepEqual(args.terms, [
|
||||||
|
{operator: "channel", operand: rome_id.toString()},
|
||||||
|
{operator: "topic", operand: ""},
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Test with no topic, with realm mandatory topics
|
||||||
|
override(realm, "realm_mandatory_topics", true);
|
||||||
compose_state.topic(undefined);
|
compose_state.topic(undefined);
|
||||||
args.called = false;
|
args.called = false;
|
||||||
message_view.to_compose_target();
|
message_view.to_compose_target();
|
||||||
assert.equal(args.called, true);
|
assert.equal(args.called, true);
|
||||||
assert.deepEqual(args.terms, [{operator: "channel", operand: rome_id.toString()}]);
|
assert.deepEqual(args.terms, [{operator: "channel", operand: rome_id.toString()}]);
|
||||||
|
|
||||||
|
// Test with no topic, without realm mandatory topics
|
||||||
|
override(realm, "realm_mandatory_topics", false);
|
||||||
|
compose_state.topic(undefined);
|
||||||
|
args.called = false;
|
||||||
|
message_view.to_compose_target();
|
||||||
|
assert.equal(args.called, true);
|
||||||
|
assert.deepEqual(args.terms, [
|
||||||
|
{operator: "channel", operand: rome_id.toString()},
|
||||||
|
{operator: "topic", operand: ""},
|
||||||
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
run_test("narrow_to_compose_target direct messages", ({override, override_rewire}) => {
|
run_test("narrow_to_compose_target direct messages", ({override, override_rewire}) => {
|
||||||
|
|||||||
Reference in New Issue
Block a user