Skip to content

Commit

Permalink
compose: Redesign limit indicator to show remaining characters count.
Browse files Browse the repository at this point in the history
Additionally, the text colors have been updated for both light and dark
themes, it starts showing when 900 or less characters are left, as 999
was too soon, and has a tooltip to show the maximum characters limit.

Fixes: zulip#28706.
  • Loading branch information
N-Shar-ma committed Apr 28, 2024
1 parent 7cc7be5 commit d7acab1
Show file tree
Hide file tree
Showing 7 changed files with 25 additions and 17 deletions.
14 changes: 8 additions & 6 deletions web/src/compose_validate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,10 @@ function update_send_button_status(): void {

export function get_disabled_send_tooltip(): string {
if (message_too_long) {
return $t({defaultMessage: "Message length shouldn't be greater than 10000 characters."});
return $t(
{defaultMessage: `Message length shouldn't be greater than {max_length} characters.`},
{max_length: realm.max_message_length},
);
} else if (upload_in_progress) {
return $t({defaultMessage: "Cannot send message while files are being uploaded."});
}
Expand Down Expand Up @@ -689,15 +692,15 @@ export function check_overflow_text(): number {
// expensive.
const text = compose_state.message_content();
const max_length = realm.max_message_length;
const remaining_characters = max_length - text.length;
const $indicator = $("#compose-limit-indicator");

if (text.length > max_length) {
$indicator.addClass("over_limit");
$("textarea#compose-textarea").addClass("over_limit");
$indicator.html(
render_compose_limit_indicator({
text_length: text.length,
max_length,
remaining_characters,
}),
);
compose_banner.show_error_message(
Expand All @@ -712,13 +715,12 @@ export function check_overflow_text(): number {
$("#compose_banners"),
);
set_message_too_long(true);
} else if (text.length > 0.9 * max_length) {
} else if (text.length >= 0.91 * max_length) {
$indicator.removeClass("over_limit");
$("textarea#compose-textarea").removeClass("over_limit");
$indicator.html(
render_compose_limit_indicator({
text_length: text.length,
max_length,
remaining_characters,
}),
);
set_message_too_long(false);
Expand Down
1 change: 1 addition & 0 deletions web/src/ui_init.js
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,7 @@ function initialize_compose_box() {
giphy_enabled: giphy.is_giphy_enabled(),
max_stream_name_length: realm.max_stream_name_length,
max_topic_length: realm.max_topic_length,
max_message_length: realm.max_message_length,
}),
),
);
Expand Down
4 changes: 4 additions & 0 deletions web/styles/app_variables.css
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,8 @@
231deg 100% 90% / 50%
);
--color-compose-chevron-arrow: hsl(0deg 0% 58%);
--color-limit-indicator: hsl(38deg 100% 36%);
--color-limit-indicator-over-limit: hsl(3deg 80% 40%);

/* Text colors */
--color-text-default: hsl(0deg 0% 20%);
Expand Down Expand Up @@ -585,6 +587,8 @@
235deg 100% 70% / 11%
);
--color-background-popover: hsl(212deg 32% 14%);
--color-limit-indicator: hsl(38deg 100% 70%);
--color-limit-indicator-over-limit: hsl(3deg 80% 60%);

/* Text colors */
--color-text-default: hsl(0deg 0% 100% / 75%);
Expand Down
10 changes: 6 additions & 4 deletions web/styles/compose.css
Original file line number Diff line number Diff line change
Expand Up @@ -304,14 +304,16 @@

#compose-limit-indicator {
font-size: 12px;
color: hsl(39deg 100% 50%);
color: var(--color-limit-indicator);
width: max-content;

/* Keep the limit indicator
just above the send button */
/* Keep the limit indicator just above
and aligned with the send button */
margin-top: auto;
padding: 3px 3px 3px 0;

&.over_limit {
color: hsl(0deg 76% 65%);
color: var(--color-limit-indicator-over-limit);
font-weight: bold;
}
}
Expand Down
2 changes: 1 addition & 1 deletion web/templates/compose.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@
<a id="compose-drafts-button" role="button" class="send-control-button hide-sm" tabindex=0 href="#drafts">
<span class="compose-drafts-text">{{t 'Drafts' }}</span><span class="compose-drafts-count-container">(<span class="compose-drafts-count"></span>)</span>
</a>
<span id="compose-limit-indicator"></span>
<span id="compose-limit-indicator" class="tippy-zulip-tooltip" data-tippy-content="{{t 'Maximum message length: {max_message_length} characters' }}"></span>
<div class="message-send-controls">
<button type="submit" id="compose-send-button" class="send_message compose-submit-button compose-send-or-save-button" aria-label="{{t 'Send' }}">
<img class="loader" alt="" src="" />
Expand Down
3 changes: 1 addition & 2 deletions web/templates/compose_limit_indicator.hbs
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
{{! Include a zero-width-space to allow breaks in narrow compose boxes. }}
{{text_length}}&ZeroWidthSpace;/{{max_length}}
{{remaining_characters}}
8 changes: 4 additions & 4 deletions web/tests/compose_validate.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -546,24 +546,24 @@ test_ui("test_check_overflow_text", ({mock_template}) => {
$textarea.val("a".repeat(10000 + 1));
compose_validate.check_overflow_text();
assert.ok($indicator.hasClass("over_limit"));
assert.equal(limit_indicator_html, "10001&ZeroWidthSpace;/10000\n");
assert.equal(limit_indicator_html, "-1\n");
assert.ok($textarea.hasClass("over_limit"));
assert.ok(banner_rendered);
assert.ok($(".message-send-controls").hasClass("disabled-message-send-controls"));

// Indicator should show orange colored text
banner_rendered = false;
$textarea.val("a".repeat(9000 + 1));
$textarea.val("a".repeat(9100));
compose_validate.check_overflow_text();
assert.ok(!$indicator.hasClass("over_limit"));
assert.equal(limit_indicator_html, "9001&ZeroWidthSpace;/10000\n");
assert.equal(limit_indicator_html, "900\n");
assert.ok(!$textarea.hasClass("over_limit"));
assert.ok(!$(".message-send-controls").hasClass("disabled-message-send-controls"));
assert.ok(!banner_rendered);

// Indicator must be empty
banner_rendered = false;
$textarea.val("a".repeat(9000));
$textarea.val("a".repeat(9100 - 1));
compose_validate.check_overflow_text();
assert.ok(!$indicator.hasClass("over_limit"));
assert.equal($indicator.text(), "");
Expand Down

0 comments on commit d7acab1

Please sign in to comment.