From 838d606f4dad8710bff6af9a33efe2529abff708 Mon Sep 17 00:00:00 2001 From: N-Shar-ma Date: Tue, 13 Feb 2024 13:58:17 +0530 Subject: [PATCH] compose: Redesign the "go to conversation" button. Now the button uses an eye icon, is placed at the start of the topic/dm recipient input, and has a bluish purple look. It slides in and out of view as needed. Fixes: #28697. (cherry picked from commit 6b8e2c2735d95f45205103f4b145d77269a3e08c) --- web/shared/icons/jump-to-conversation.svg | 5 + web/src/compose_actions.ts | 8 +- web/src/compose_recipient.ts | 31 +++++- web/src/compose_setup.js | 10 +- web/styles/app_variables.css | 12 +++ web/styles/compose.css | 126 +++++++++++++--------- web/styles/dark_theme.css | 11 +- web/styles/input_pill.css | 4 +- web/templates/compose.hbs | 5 +- 9 files changed, 140 insertions(+), 72 deletions(-) create mode 100644 web/shared/icons/jump-to-conversation.svg diff --git a/web/shared/icons/jump-to-conversation.svg b/web/shared/icons/jump-to-conversation.svg new file mode 100644 index 00000000000000..4e27c7a7f1307a --- /dev/null +++ b/web/shared/icons/jump-to-conversation.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/web/src/compose_actions.ts b/web/src/compose_actions.ts index 19cb224eb6052c..d08c194d3d871a 100644 --- a/web/src/compose_actions.ts +++ b/web/src/compose_actions.ts @@ -162,7 +162,7 @@ export function complete_starting_tasks(opts: ComposeActionsOpts): void { compose_fade.start_compose(opts.message_type); $(document).trigger(new $.Event("compose_started.zulip", opts)); compose_recipient.update_placeholder_text(); - compose_recipient.update_narrow_to_recipient_visibility(); + compose_recipient.update_narrow_to_recipient_visibility(true); } export function maybe_scroll_up_selected_message(opts: ComposeActionsStartOpts): void { @@ -341,11 +341,11 @@ export function start(raw_opts: ComposeActionsStartOpts): void { $("textarea#compose-textarea").data("draft-id", opts.draft_id); } - const $clear_topic_button = $("#recipient_box_clear_topic_button"); + const $compose_recipient_box = $("#compose_recipient_box"); if (is_clear_topic_button_triggered || opts.topic.length === 0) { - $clear_topic_button.hide(); + $compose_recipient_box.toggleClass("empty", true); } else { - $clear_topic_button.show(); + $compose_recipient_box.toggleClass("empty", false); } // Show a warning if topic is resolved diff --git a/web/src/compose_recipient.ts b/web/src/compose_recipient.ts index 3477dd74867232..f4f223e4a863e7 100644 --- a/web/src/compose_recipient.ts +++ b/web/src/compose_recipient.ts @@ -34,6 +34,10 @@ type DirectMessagesOption = { name: string; }; +// This state variable tracks whether the narrow_to_compose_recipients +// button should be shown when beside the topic input, on blur. +let show_narrow_to_compose_recipients = true; + function composing_to_current_topic_narrow(): boolean { return ( util.lower_same(compose_state.stream_name(), narrow_state.stream_name() ?? "") && @@ -63,7 +67,14 @@ function composing_to_current_private_message_narrow(): boolean { ); } -export function update_narrow_to_recipient_visibility(): void { +export function update_narrow_to_recipient_visibility(opening_compose = false): void { + // We skip the transition when opening a collapsed compose box. + if (opening_compose) { + $(".narrow_to_compose_recipients").toggleClass("no-transition", true); + setTimeout(() => { + $(".narrow_to_compose_recipients").toggleClass("no-transition", false); + }, 10); + } const message_type = compose_state.get_message_type(); if (message_type === "stream") { const stream_exists = Boolean(compose_state.stream_id()); @@ -73,9 +84,15 @@ export function update_narrow_to_recipient_visibility(): void { !composing_to_current_topic_narrow() && compose_state.has_full_recipient() ) { - $(".narrow_to_compose_recipients").toggleClass("invisible", false); + show_narrow_to_compose_recipients = true; + // If focus is in the adjacent input, we slide in the button later on blur. + if (!$("#stream_message_recipient_topic").is(":focus")) { + // Else, we slide in the button immediately. + $(".narrow_to_compose_recipients").toggleClass("collapsed", false); + } return; } + show_narrow_to_compose_recipients = false; } else if (message_type === "private") { const recipients = compose_state.private_message_recipient(); if ( @@ -83,11 +100,11 @@ export function update_narrow_to_recipient_visibility(): void { !composing_to_current_private_message_narrow() && compose_state.has_full_recipient() ) { - $(".narrow_to_compose_recipients").toggleClass("invisible", false); + $(".narrow_to_compose_recipients").toggleClass("collapsed", false); return; } } - $(".narrow_to_compose_recipients").toggleClass("invisible", true); + $(".narrow_to_compose_recipients").toggleClass("collapsed", true); } function update_fade(): void { @@ -354,6 +371,12 @@ export function initialize(): void { update_on_recipient_change(); compose_state.set_recipient_edited_manually(true); }); + + $("#stream_message_recipient_topic").on("blur", () => { + if (show_narrow_to_compose_recipients) { + $(".narrow_to_compose_recipients").toggleClass("collapsed", false); + } + }); } export function update_placeholder_text(): void { diff --git a/web/src/compose_setup.js b/web/src/compose_setup.js index 86ac882ccf4cd5..b23c8e90b4bbcd 100644 --- a/web/src/compose_setup.js +++ b/web/src/compose_setup.js @@ -440,20 +440,20 @@ export function initialize() { $("#compose_recipient_box").on("click", "#recipient_box_clear_topic_button", () => { const $input = $("input#stream_message_recipient_topic"); - const $button = $("#recipient_box_clear_topic_button"); + const $container = $("#compose_recipient_box"); $input.val(""); $input.trigger("focus"); - $button.hide(); + $container.toggleClass("empty", true); }); $("#compose_recipient_box").on("input", "input#stream_message_recipient_topic", (e) => { - const $button = $("#recipient_box_clear_topic_button"); + const $container = $("#compose_recipient_box"); const value = $(e.target).val(); if (value.length === 0) { - $button.hide(); + $container.toggleClass("empty", true); } else { - $button.show(); + $container.toggleClass("empty", false); } }); diff --git a/web/styles/app_variables.css b/web/styles/app_variables.css index 42cc938d81d422..55c518206b0812 100644 --- a/web/styles/app_variables.css +++ b/web/styles/app_variables.css @@ -278,6 +278,14 @@ --color-compose-chevron-arrow: hsl(0deg 0% 58%); --color-limit-indicator: hsl(38deg 100% 36%); --color-limit-indicator-over-limit: hsl(3deg 80% 40%); + --color-narrow-to-compose-recipients-background: hsl(227deg 100% 70% / 25%); + --color-narrow-to-compose-recipients-background-hover: hsl( + 227deg 100% 70% / 35% + ); + --color-narrow-to-compose-recipients-color: hsl(227deg 76% 64%); + --color-narrow-to-compose-recipients-color-hover: hsl(227deg 78% 59%); + --color-narrow-to-compose-recipients-border: transparent; + --color-compose-recipient-box-border: hsl(0deg 0% 0% / 20%); /* Text colors */ --color-text-default: hsl(0deg 0% 20%); @@ -595,6 +603,10 @@ --color-background-popover: hsl(212deg 32% 14%); --color-limit-indicator: hsl(38deg 100% 70%); --color-limit-indicator-over-limit: hsl(3deg 80% 60%); + --color-narrow-to-compose-recipients-color: hsl(224deg 28% 81%); + --color-narrow-to-compose-recipients-color-hover: hsl(221deg 100% 95%); + --color-narrow-to-compose-recipients-border: hsl(210deg 9% 4%); + --color-compose-recipient-box-border: hsl(0deg 0% 0% / 60%); /* Text colors */ --color-text-default: hsl(0deg 0% 100% / 75%); diff --git a/web/styles/compose.css b/web/styles/compose.css index 4dd717ce536dc1..4a0d287e47dc10 100644 --- a/web/styles/compose.css +++ b/web/styles/compose.css @@ -185,19 +185,36 @@ } & a.narrow_to_compose_recipients { - background: transparent; - font-size: 18px; - padding: 0 1px; - align-self: center; + display: flex; + align-items: center; + background: var(--color-narrow-to-compose-recipients-background); + color: var(--color-narrow-to-compose-recipients-color); + border: 1px solid var(--color-narrow-to-compose-recipients-border); + font-size: 20px; + /* extra 3px padding, and -ive 4px margin on the right so that the curved + edge of the next element will overlap the 3px padding + 1 px border by 4px */ + padding: 0 7px 0 4px; + margin-right: -4px; line-height: 20px; - opacity: 0.7; - border: 0; - margin-left: 3px; text-decoration: none; - color: inherit; + transition: all 100ms ease-in-out; + border-radius: 4px 0 0 4px; &:hover { - opacity: 1; + background: var( + --color-narrow-to-compose-recipients-background-hover + ); + color: var(--color-narrow-to-compose-recipients-color-hover); + } + + &.no-transition { + transition: none; + } + + &.collapsed { + width: 0; + padding: 0; + border-width: 0; } } } @@ -205,7 +222,7 @@ #compose-direct-recipient { flex-grow: 1; display: grid; - grid-template-columns: 1fr; + grid-template-columns: auto 1fr; align-items: stretch; } @@ -348,18 +365,18 @@ align-items: center; height: var(--compose-recipient-box-min-height); /* Align to compose controls; that's 112px width, - minus 23px for the narrow indicator, but then - add back 6px of grid gap for 95px here. + but then add back 6px of grid gap for 118px + here. TODO: Make variables here; expanded use of grid on the compose box will make these unnecessary, eventually. */ - width: calc(112px - 23px + 6px); + width: calc(112px + 6px); justify-content: flex-end; @media ((width >= $sm_min) and (width < $mc_min)) { /* Align to compose controls at narrower widths */ - width: calc(62px - 23px + 6px); + width: calc(62px + 6px); } @media (width < $sm_min) { @@ -717,8 +734,17 @@ textarea.new_message_textarea { resize: vertical !important; margin-top: 5px; border-radius: 4px; - color: hsl(0deg 0% 33%); background-color: hsl(0deg 0% 100%); + border: 1px solid hsl(0deg 0% 0% / 20%); + box-shadow: none; + transition: border 0.2s ease; + color: var(--color-text-default); + + &:focus { + outline: 0; + border: 1px solid hsl(0deg 0% 67%); + box-shadow: none; + } &.over_limit, &.over_limit:focus { @@ -742,41 +768,23 @@ textarea.new_message_textarea { } } -textarea.new_message_textarea, -#compose_recipient_box { - border: 1px solid hsl(0deg 0% 0% / 20%); - box-shadow: none; - transition: border 0.2s ease; - color: var(--color-text-default); - - &:focus { - outline: 0; - border: 1px solid hsl(0deg 0% 67%); - box-shadow: none; - } -} - #compose_recipient_box { display: grid; - grid-template-columns: 1fr auto; + grid-template-columns: auto 1fr auto; align-items: stretch; flex: 1 1 0; - border-radius: 3px; + border-radius: 4px; background: hsl(0deg 0% 100%); - /* Give the recipient box, a `
`, the - correct styles when focus is in the - #stream_message_recipient_topic `` */ - &:focus-within { - outline: 0; - border: 1px solid hsl(0deg 0% 67%); - box-shadow: none; - } - #stream_message_recipient_topic, #recipient_box_clear_topic_button { - background: none; - border: none; + /* background: none makes the topic input transparent in which + case it would not hide the edge of .narrow_to_compose_recipients + it overlaps, hence we use inherit instead */ + background: inherit; + /* We make the borders of both these elements look like 1 + single element's border */ + border: 1px solid var(--color-compose-recipient-box-border); } /* Styles for input in the recipient_box */ @@ -784,21 +792,21 @@ textarea.new_message_textarea, /* Override grid's effective `max-content` min-width */ overflow: hidden; text-overflow: ellipsis; - box-shadow: none; outline: none; - - padding: 4px 6px; - /* Reset height to let `align-items: stretch` on the grid parent handle this. */ + border-right: none; + border-radius: 4px 0 0 4px; + /* Reset height to let `align-items: stretch` on the grid parent handle this */ height: auto; + padding: 4px; } /* Styles for new conversation button in the recipient_box */ #recipient_box_clear_topic_button { - /* Set the border radius smaller, relative to the parent */ - border-radius: 2px; + border-left: none; + border-radius: 0 4px 4px 0; padding: 6px; - margin: 1px; + margin: 0; color: var(--color-compose-embedded-button-text-color); .zulip-icon { @@ -817,6 +825,26 @@ textarea.new_message_textarea, } } + &.empty { + #stream_message_recipient_topic { + border-radius: 4px; + border-right: 1px solid var(--color-compose-recipient-box-border); + } + + #recipient_box_clear_topic_button { + display: none; + } + } + + /* Darken the combined border of the topic input and clear + topic button when focus is in the topic input */ + &:focus-within { + #stream_message_recipient_topic, + #recipient_box_clear_topic_button { + border-color: hsl(0deg 0% 67%); + } + } + /* This will reset the bootstrap margin-bottom: 10px value for the inputs */ & input { margin-bottom: 0; diff --git a/web/styles/dark_theme.css b/web/styles/dark_theme.css index 92b52ebe17da25..cb767a8fa8ee64 100644 --- a/web/styles/dark_theme.css +++ b/web/styles/dark_theme.css @@ -447,6 +447,12 @@ color: inherit; } + #compose_recipient_box, + #compose-direct-recipient .pill-container { + /* Opaque to overlap .narrow_to_compose_recipients button */ + background-color: hsl(231deg 11% 14%); + } + .dropdown-list-search .dropdown-list-search-input:focus { background-color: hsl(225deg 6% 7%); border: 1px solid hsl(0deg 0% 100% / 50%); @@ -476,10 +482,6 @@ background-color: hsl(0deg 86% 14%) !important; } - #compose-direct-recipient .pill-container { - background-color: hsl(0deg 0% 0% / 20%); - } - #searchbox { /* Light theme shows hover mostly through box-shadow, and dark theme shows it mostly through changing color @@ -611,7 +613,6 @@ } } - .narrow_to_compose_recipients, .expand_composebox_button, .collapse_composebox_button, .clear_search_button, diff --git a/web/styles/input_pill.css b/web/styles/input_pill.css index b52ecb59c779ea..5d67c4e7a12a8c 100644 --- a/web/styles/input_pill.css +++ b/web/styles/input_pill.css @@ -122,8 +122,8 @@ } #compose-direct-recipient .pill-container { - padding: 0 2px; - border: 1px solid hsl(0deg 0% 0% / 20%); + padding: 0; + border: 1px solid var(--color-compose-recipient-box-border); background-color: hsl(0deg 0% 100%); .input { diff --git a/web/templates/compose.hbs b/web/templates/compose.hbs index b7916a83917566..949d35cc10ada6 100644 --- a/web/templates/compose.hbs +++ b/web/templates/compose.hbs @@ -55,21 +55,20 @@
-
- -
{{> dropdown_widget_wrapper widget_name="compose_select_recipient"}}
+
+