frontend: Change 'reply' button label to reflect selected message.

The 'reply' button shows the stream>topic or recipient(s) of the
selected message, for better UX.  It also expands to fill the
remaining horizontal space in the button bar -- this should help make
it easier for new users to figure out how to reply.

Finally, it uses "Message" instead of "Reply", to better match the
compose box.

Fixes #17940.
This commit is contained in:
Ken Clary 2021-04-15 00:59:34 +00:00 committed by Tim Abbott
parent ddb9d16132
commit 74dbcdf2a8
6 changed files with 176 additions and 23 deletions

View File

@ -0,0 +1,88 @@
"use strict";
// Setup
const {strict: assert} = require("assert");
const {mock_cjs, mock_esm, set_global, zrequire} = require("../zjsunit/namespace");
const {run_test} = require("../zjsunit/test");
const $ = require("../zjsunit/zjquery");
// Mocking and stubbing things
mock_cjs("jquery", $);
set_global("document", "document-stub");
const message_lists = mock_esm("../../static/js/message_lists");
// Code we're actually using/testing
const compose_closed_ui = zrequire("compose_closed_ui");
const {MessageList} = zrequire("message_list");
// Helper test function
function test_reply_label(expected_label) {
const label = $(".compose_reply_button_recipient_label").text();
assert.equal(label, expected_label, "'" + label + "' did not match '" + expected_label + "'");
}
run_test("reply_label", () => {
// Mocking up a test message list
const filter = {
predicate: () => () => true,
};
const list = new MessageList({
filter,
});
message_lists.current = list;
list.add_messages([
{
id: 0,
stream: "first_stream",
topic: "first_topic",
},
{
id: 1,
stream: "first_stream",
topic: "second_topic",
},
{
id: 2,
stream: "second_stream",
topic: "third_topic",
},
{
id: 3,
stream: "second_stream",
topic: "second_topic",
},
{
id: 4,
display_reply_to: "some user",
},
{
id: 5,
display_reply_to: "some user, other user",
},
]);
const expected_labels = [
"#first_stream > first_topic",
"#first_stream > second_topic",
"#second_stream > third_topic",
"#second_stream > second_topic",
"some user",
"some user, other user",
];
// Initialize the code we're testing.
compose_closed_ui.initialize();
// Run the tests!
let first = true;
for (const expected_label of expected_labels) {
if (first) {
list.select_id(list.first().id);
first = false;
} else {
list.select_id(list.next());
}
test_reply_label(expected_label);
}
});

View File

@ -0,0 +1,25 @@
import $ from "jquery";
import * as message_lists from "./message_lists";
function update_reply_recipient_label() {
const message = message_lists.current.selected_message();
let recipient_label = "";
if (message) {
if (message.stream && message.topic) {
recipient_label = "#" + message.stream + " > " + message.topic;
} else if (message.display_reply_to) {
recipient_label = message.display_reply_to;
}
}
$(".compose_reply_button_recipient_label").text(recipient_label);
}
// TODO: Move the closed-compose buttons click handlers here, probably.
export function initialize() {
// When the message selection changes, change the label on the Reply button.
$(document).on("message_selected.zulip", () => {
update_reply_recipient_label();
});
}

View File

@ -13,6 +13,7 @@ import * as blueslip from "./blueslip";
import * as bot_data from "./bot_data";
import * as click_handlers from "./click_handlers";
import * as compose from "./compose";
import * as compose_closed_ui from "./compose_closed_ui";
import * as compose_pm_pill from "./compose_pm_pill";
import * as composebox_typeahead from "./composebox_typeahead";
import * as condense from "./condense";
@ -470,6 +471,7 @@ export function initialize_everything() {
scroll_bar.initialize();
message_viewport.initialize();
panels.initialize();
compose_closed_ui.initialize();
initialize_kitchen_sink_stuff();
echo.initialize();
stream_edit.initialize();

View File

@ -1,13 +1,17 @@
#compose_buttons {
text-align: right;
display: flex;
flex-direction: row;
align-items: center;
.new_message_button {
padding-top: 1.1em;
margin-left: 4px;
.button.small {
font-size: 1em;
padding: 3px 10px;
vertical-align: middle;
background-color: hsla(0, 0%, 0%, 0.1);
}
.compose_mobile_button {
@ -16,10 +20,6 @@
font-weight: 400;
line-height: 1em;
}
@media (width >= $sm_min) {
display: none;
}
}
.message-control-link {
@ -29,27 +29,49 @@
.alert-draft {
font-size: 14px;
color: hsl(170, 48%, 54%);
padding: 3px 12px;
padding: 0 12px;
font-weight: 400;
display: none;
}
}
@media (width < $sm_min) {
.compose_stream_button,
.compose_private_button {
display: none;
.reply_button_container {
flex: 1;
min-width: 0;
margin-left: 0;
.compose_reply_button {
width: 100%;
text-align: left;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
.compose_reply_button_recipient_label {
color: hsl(215, 47%, 30%);
}
}
}
.mobile_button_container {
@media (width >= $sm_min) {
display: none;
}
}
.stream_button_container,
.private_button_container {
@media (width < $sm_min) {
display: none;
}
}
}
/* Main geometry for this element is in zulip.css */
.compose-content {
border-top: 1px solid hsla(0, 0%, 0%, 0.07);
transition: background-color 200ms linear;
padding: 8px 10px 8px 10px;
padding: 4px 4px 8px 4px;
border-left: 1px solid hsl(0, 0%, 93%);
border-right: 1px solid hsl(0, 0%, 93%);
}

View File

@ -32,6 +32,17 @@ body.night-mode {
background-color: hsl(212, 28%, 18%);
}
#compose_buttons .new_message_button .button.small {
background-color: hsla(0, 0%, 0%, 0.2);
}
#compose_buttons
.reply_button_container
.compose_reply_button
.compose_reply_button_recipient_label {
color: hsl(215, 47%, 80%);
}
.compose-send-status-close {
color: hsl(0, 0%, 100%);
opacity: 1;

View File

@ -5,20 +5,32 @@
<span id="compose-reply-error-msg"></span>
</div>
<div id="compose_buttons">
<span class="new_message_button reply_button_container">
<button type="button" class="button small rounded compose_reply_button"
id="left_bar_compose_reply_button_big"
title="{{t 'Reply' }} (r)">
<span class="compose_reply_button_label">
{{#tr}}
Message <z-recipient></z-recipient>
{{#*inline "z-recipient"}}<span class="compose_reply_button_recipient_label"></span>{{/inline}}
{{/tr}}
</span>
</button>
</span>
<span class="new_message_button">
<a class="drafts-link no-underline button small rounded compose_drafts_button" href="#drafts" title="{{t 'Drafts' }} (d)">
{{t 'Drafts' }}
</a>
<span class="alert-draft pull-left">{{t 'Saved as draft' }}</span>
</span>
<span class="new_message_button">
<span class="new_message_button mobile_button_container">
<button type="button" class="button small rounded compose_mobile_button"
id="left_bar_compose_mobile_button_big"
title="{{t 'New message' }} (c)">
<span>+</span>
</button>
</span>
<span class="new_message_button">
<span class="new_message_button stream_button_container">
<button type="button" class="button small rounded compose_stream_button"
id="left_bar_compose_stream_button_big"
title="{{t 'New topic' }} (c)">
@ -26,7 +38,7 @@
</button>
</span>
{{#unless embedded }}
<span class="new_message_button">
<span class="new_message_button private_button_container">
<button type="button" class="button small rounded compose_private_button"
id="left_bar_compose_private_button_big"
title="{{t 'New private message' }} (x)">
@ -34,13 +46,6 @@
</button>
</span>
{{/unless}}
<span class="new_message_button">
<button type="button" class="button small rounded compose_reply_button"
id="left_bar_compose_reply_button_big"
title="{{t 'Reply' }} (r)">
<span class="compose_reply_button_label">{{t 'Reply' }}</span>
</button>
</span>
</div>
</div>
<div class="message_comp compose-content">