compose: Add ability to switch to PM in stream dropdown.

Fixes #3409
This commit is contained in:
evykassirer
2023-04-14 18:35:23 -07:00
committed by Tim Abbott
parent e4fc197871
commit 18312be6db
11 changed files with 99 additions and 62 deletions

View File

@@ -106,9 +106,9 @@ async function test_open_close_compose_box(page: Page): Promise<void> {
await page.waitForSelector("#stream_message_recipient_topic", {hidden: true});
await page.keyboard.press("KeyX");
await page.waitForSelector("#compose-private-recipient", {visible: true});
await page.waitForSelector("#compose-direct-recipient", {visible: true});
await close_compose_box(page);
await page.waitForSelector("#compose-private-recipient", {hidden: true});
await page.waitForSelector("#compose-direct-recipient", {hidden: true});
}
async function test_narrow_to_private_messages_with_cordelia(page: Page): Promise<void> {

View File

@@ -169,7 +169,7 @@ async function test_restore_private_message_draft_via_draft_overlay(page: Page):
console.log("Restoring private message draft.");
await page.click(".message_row.private-message .restore-draft");
await wait_for_drafts_to_disappear(page);
await page.waitForSelector("#compose-private-recipient", {visible: true});
await page.waitForSelector("#compose-direct-recipient", {visible: true});
await common.check_compose_state(page, {
content: "Test private message.",
});
@@ -201,7 +201,7 @@ async function test_delete_draft(page: Page): Promise<void> {
async function test_save_draft_by_reloading(page: Page): Promise<void> {
console.log("Saving draft by reloading.");
await page.keyboard.press("KeyX");
await page.waitForSelector("#compose-private-recipient", {visible: true});
await page.waitForSelector("#compose-direct-recipient", {visible: true});
await common.fill_form(page, "form#send_message_form", {
content: "Test private message draft.",
});

View File

@@ -41,7 +41,7 @@ function hide_box() {
drafts.update_draft();
blur_compose_inputs();
$("#stream_message_recipient_topic").hide();
$("#compose-private-recipient").hide();
$("#compose-direct-recipient").hide();
$(".new_message_textarea").css("min-height", "");
compose_fade.clear_compose();
$(".message_comp").hide();
@@ -79,17 +79,24 @@ export function set_focus(msg_type, opts) {
}
}
function show_compose_box(msg_type, opts) {
export function show_compose_box(msg_type, opts) {
if (msg_type === "stream") {
$("#compose-private-recipient").hide();
$("#compose-direct-recipient").hide();
$("#stream_message_recipient_topic").show();
$("#stream_toggle").addClass("active");
$("#private_message_toggle").removeClass("active");
$("#compose-recipient").removeClass("compose-recipient-direct-selected");
} else {
$("#compose-private-recipient").show();
$("#compose-direct-recipient").show();
$("#stream_message_recipient_topic").hide();
$("#stream_toggle").removeClass("active");
$("#private_message_toggle").addClass("active");
$("#compose-recipient").addClass("compose-recipient-direct-selected");
// TODO: When "Direct message" is selected, we show "DM" on the dropdown
// button. It would be nice if the dropdown supported a way to attach
// the "DM" button display string so we wouldn't have to manually change
// it here.
$("#compose_select_recipient_name").text($t({defaultMessage: "DM"}));
}
compose_banner.clear_errors();
compose_banner.clear_warnings();
@@ -97,6 +104,9 @@ function show_compose_box(msg_type, opts) {
// When changing this, edit the 42px in _maybe_autoscroll
$(".new_message_textarea").css("min-height", "3em");
if (opts.trigger === "toggle recipient type") {
update_placeholder_text();
}
set_focus(msg_type, opts);
}

View File

@@ -3,6 +3,8 @@
import $ from "jquery";
import _ from "lodash";
// todo: fix circular import here
import * as compose_actions from "./compose_actions";
import * as compose_banner from "./compose_banner";
import * as compose_fade from "./compose_fade";
import * as compose_state from "./compose_state";
@@ -16,6 +18,8 @@ import * as util from "./util";
export let compose_recipient_widget;
const DIRECT_MESSAGE = "direct";
function composing_to_current_topic_narrow() {
return (
util.lower_same(compose_state.stream_name(), narrow_state.stream() || "") &&
@@ -121,15 +125,47 @@ export function check_stream_posting_policy_for_compose_box(stream_name) {
}
}
export function on_compose_select_recipient_update(new_value) {
const $stream_header_colorblock = $("#compose_recipient_selection_dropdown").find(
".stream_header_colorblock",
);
stream_bar.decorate(new_value, $stream_header_colorblock);
update_on_recipient_change();
$("#stream_message_recipient_topic").trigger("focus").trigger("select");
function switch_message_type(message_type) {
$("#compose-content .alert").hide();
check_stream_posting_policy_for_compose_box(new_value);
compose_state.set_message_type(message_type);
const opts = {
message_type,
trigger: "toggle recipient type",
stream: compose_state.stream_name(),
topic: compose_state.topic(),
private_message_recipient: compose_state.private_message_recipient(),
};
compose_actions.show_compose_box(message_type, opts);
}
export function on_compose_select_recipient_update(new_value) {
const message_type = compose_state.get_message_type();
if (new_value === DIRECT_MESSAGE) {
// TODO: In theory, we could do something more lightweight in
// the case it's already that value, but doing nothing would
// display the wrong and fail to update focus properly.
switch_message_type("private");
if (compose_state.private_message_recipient().length === 0) {
$("#private_message_recipient").trigger("focus").trigger("select");
}
} else {
const $stream_header_colorblock = $("#compose_recipient_selection_dropdown").find(
".stream_header_colorblock",
);
stream_bar.decorate(new_value, $stream_header_colorblock);
if (message_type === "private") {
switch_message_type("stream");
}
// Always move focus to the topic input even if it's not empty,
// since it's likely the user will want to update the topic
// after updating the stream.
$("#stream_message_recipient_topic").trigger("focus").trigger("select");
check_stream_posting_policy_for_compose_box(new_value);
}
update_on_recipient_change();
}
export function update_stream_dropdown_options() {
@@ -144,7 +180,7 @@ export function possibly_update_dropdown_selection(old_stream_name, new_stream_n
}
function get_options_for_recipient_widget() {
return stream_data
const options = stream_data
.subscribed_subs()
.map((stream) => ({
name: stream.name,
@@ -160,6 +196,13 @@ function get_options_for_recipient_widget() {
}
return 0;
});
const direct_messages_option = {
name: $t({defaultMessage: "Direct message"}),
value: DIRECT_MESSAGE,
};
options.unshift(direct_messages_option);
return options;
}
export function initialize() {

View File

@@ -101,13 +101,22 @@
}
}
.right_part,
#stream_message_recipient_topic {
#compose-recipient {
padding: 0;
display: flex;
align-items: center;
flex: 1;
&.compose-recipient-direct-selected {
#compose_recipient_selection_dropdown .dropdown-toggle {
border-radius: 4px !important;
}
.stream_header_colorblock {
display: none;
}
}
.fa-angle-right {
font-size: 0.9em;
-webkit-text-stroke: 0.05em;
@@ -132,17 +141,8 @@
}
}
.pm_recipient {
margin-left: 5px;
display: flex;
align-items: center;
width: 100%;
}
#compose-private-recipient .to_text {
vertical-align: middle;
font-weight: 600;
#compose-direct-recipient {
flex-grow: 1;
}
.message_header {
@@ -616,12 +616,9 @@ input.recipient_box {
}
}
#stream_message_recipient_topic,
#compose-private-recipient {
#compose-recipient {
min-width: 0;
display: flex;
}
#compose-private-recipient {
align-items: center;
width: 100%;
}

View File

@@ -475,7 +475,7 @@
}
#search_arrows .pill,
.pm_recipient .pill-container .pill {
#compose-direct-recipient.pill-container .pill {
color: inherit;
border: 1px solid hsl(0deg 0% 0% / 50%);
background-color: hsl(0deg 0% 0% / 25%);
@@ -483,7 +483,7 @@
}
#search_arrows .pill:focus,
.pm_recipient .pill-container .pill:focus {
#compose-direct-recipient.pill-container .pill:focus {
color: hsl(0deg 0% 100%);
border: 1px solid hsl(176deg 78% 28% / 60%);
background-color: hsl(176deg 49% 42% / 40%);

View File

@@ -109,7 +109,7 @@
}
}
.pm_recipient .pill-container {
#compose-direct-recipient.pill-container {
padding: 0 2px;
flex-grow: 1;
align-content: center;

View File

@@ -93,29 +93,18 @@
{{tooltip_hotkey_hints "Esc"}}
</template>
</div>
<div id="compose-stream-recipient" class="order-1">
<a role="button" class="narrow_to_compose_recipients zulip-icon zulip-icon-arrow-left-circle order-1" data-tooltip-template-id="narrow_to_compose_recipients_tooltip" tabindex="0">
</a>
<div id="compose-recipient" class="order-1">
<a role="button" class="narrow_to_compose_recipients zulip-icon zulip-icon-arrow-left-circle order-1" data-tooltip-template-id="narrow_to_compose_recipients_tooltip" tabindex="0"></a>
<div id="compose_recipient_selection_dropdown" class="new-style">
<div class="stream_header_colorblock"></div>
{{> settings/dropdown_list_widget
widget_name="compose_select_recipient"
list_placeholder=(t 'Filter streams')}}
list_placeholder=(t 'Filter')}}
</div>
<i class="fa fa-angle-right" aria-hidden="true"></i>
<input type="text" class="recipient_box" name="stream_message_recipient_topic" id="stream_message_recipient_topic" maxlength="{{ max_topic_length }}" value="" placeholder="{{t 'Topic' }}" autocomplete="off" tabindex="0" aria-label="{{t 'Topic' }}" />
</div>
<div id="compose-private-recipient" class="order-1">
<div class="to_text">
<span>{{t 'To' }}:</span>
</div>
<div class="right_part">
<div class="pm_recipient">
<a role="button" class="narrow_to_compose_recipients zulip-icon zulip-icon-arrow-left-circle order-1" data-tooltip-template-id="narrow_to_compose_recipients_tooltip" tabindex="0"></a>
<div class="pill-container" data-before="{{t 'You and' }}">
<div class="input" contenteditable="true" id="private_message_recipient" data-no-recipients-text="{{t 'Add one or more users' }}" data-some-recipients-text="{{t 'Add another user...' }}"></div>
</div>
</div>
<div id="compose-direct-recipient" class="pill-container" data-before="{{t 'You and' }}">
<div class="input" contenteditable="true" id="private_message_recipient" data-no-recipients-text="{{t 'Add one or more users' }}" data-some-recipients-text="{{t 'Add another user...' }}"></div>
</div>
</div>
</div>

View File

@@ -766,8 +766,7 @@ test_ui("on_events", ({override}) => {
test_ui("create_message_object", ({override, override_rewire}) => {
mock_stream_header_colorblock();
mock_banners();
override_rewire(stream_bar, "decorate", noop);
override_rewire(compose_recipient, "update_on_recipient_change", noop);
override_rewire(compose_recipient, "on_compose_select_recipient_update", noop);
compose_state.set_stream_name("social");
$("#stream_message_recipient_topic").val("lunch");

View File

@@ -148,7 +148,7 @@ test("start", ({override, override_rewire}) => {
start("stream", opts);
assert_visible("#stream_message_recipient_topic");
assert_hidden("#compose-private-recipient");
assert_hidden("#compose-direct-recipient");
assert.equal(compose_state.stream_name(), "stream1");
assert.equal(compose_state.topic(), "topic1");
@@ -209,7 +209,7 @@ test("start", ({override, override_rewire}) => {
start("private", opts);
assert_hidden("#stream_message_recipient_topic");
assert_visible("#compose-private-recipient");
assert_visible("#compose-direct-recipient");
assert.equal(compose_state.private_message_recipient(), "foo@example.com");
assert.equal($("#compose-textarea").val(), "hello");
@@ -245,7 +245,7 @@ test("start", ({override, override_rewire}) => {
assert.ok(abort_xhr_called);
assert.ok(pill_cleared);
assert_visible("#compose_controls");
assert_hidden("#compose-private-recipient");
assert_hidden("#compose-direct-recipient");
assert.ok(!compose_state.composing());
});
@@ -254,7 +254,7 @@ test("respond_to_message", ({override, override_rewire}) => {
override_rewire(compose_actions, "set_focus", () => {});
override_rewire(compose_actions, "complete_starting_tasks", () => {});
override_rewire(compose_actions, "clear_textarea", () => {});
override_rewire(compose_recipient, "update_on_recipient_change", () => {});
override_rewire(compose_recipient, "on_compose_select_recipient_update", noop);
override_private_message_recipient({override});
mock_stream_header_colorblock();

View File

@@ -700,8 +700,7 @@ function sorted_names_from(subs) {
test("initialize", ({override, override_rewire, mock_template}) => {
mock_stream_header_colorblock();
mock_banners();
override_rewire(compose_recipient, "update_on_recipient_change", noop);
override_rewire(stream_bar, "decorate", noop);
override_rewire(compose_recipient, "on_compose_select_recipient_update", noop);
let pill_items = [];
let cleared = false;