diff --git a/plugins/chat/assets/javascripts/discourse/components/chat-composer-dropdown.hbs b/plugins/chat/assets/javascripts/discourse/components/chat-composer-dropdown.hbs index 162fdcb3e52..9a9aabd7c71 100644 --- a/plugins/chat/assets/javascripts/discourse/components/chat-composer-dropdown.hbs +++ b/plugins/chat/assets/javascripts/discourse/components/chat-composer-dropdown.hbs @@ -9,6 +9,7 @@ "chat-composer-dropdown__trigger-btn" (if @hasActivePanel "has-active-panel") }} + ...attributes /> {{#if this.isExpanded}} diff --git a/plugins/chat/assets/javascripts/discourse/components/chat-composer-inline-buttons.hbs b/plugins/chat/assets/javascripts/discourse/components/chat-composer-inline-buttons.hbs deleted file mode 100644 index 380d5eef66e..00000000000 --- a/plugins/chat/assets/javascripts/discourse/components/chat-composer-inline-buttons.hbs +++ /dev/null @@ -1,7 +0,0 @@ -{{#each this.buttons as |button|}} - -{{/each}} \ No newline at end of file diff --git a/plugins/chat/assets/javascripts/discourse/components/chat-composer-inline-buttons.js b/plugins/chat/assets/javascripts/discourse/components/chat-composer-inline-buttons.js deleted file mode 100644 index 88361c29398..00000000000 --- a/plugins/chat/assets/javascripts/discourse/components/chat-composer-inline-buttons.js +++ /dev/null @@ -1,5 +0,0 @@ -import Component from "@ember/component"; - -export default class ChatComposerInlineButtons extends Component { - tagName = ""; -} diff --git a/plugins/chat/assets/javascripts/discourse/components/chat-composer.hbs b/plugins/chat/assets/javascripts/discourse/components/chat-composer.hbs index 83aa78afc25..4402a8d2760 100644 --- a/plugins/chat/assets/javascripts/discourse/components/chat-composer.hbs +++ b/plugins/chat/assets/javascripts/discourse/components/chat-composer.hbs @@ -39,6 +39,8 @@ this.context }} @onCloseActivePanel={{this.chatEmojiPickerManager.close}} + {{on "focus" (fn this.computeIsFocused true)}} + {{on "blur" (fn this.computeIsFocused false)}} />
+ {{#if this.inlineButtons.length}} + {{#each this.inlineButtons as |button|}} + + {{/each}} + + + {{/if}} + - - {{#unless this.disabled}} - - {{/unless}} diff --git a/plugins/chat/assets/javascripts/discourse/components/chat-composer.js b/plugins/chat/assets/javascripts/discourse/components/chat-composer.js index 9fbbca65560..e1a25c7d292 100644 --- a/plugins/chat/assets/javascripts/discourse/components/chat-composer.js +++ b/plugins/chat/assets/javascripts/discourse/components/chat-composer.js @@ -122,6 +122,13 @@ export default class ChatComposer extends Component { cancel(this._persistHandler); } + @action + handleInlineButonAction(buttonAction, event) { + event.stopPropagation(); + + buttonAction(); + } + get currentMessage() { return this.composer.message; } diff --git a/plugins/chat/assets/javascripts/discourse/components/chat/composer/separator.hbs b/plugins/chat/assets/javascripts/discourse/components/chat/composer/separator.hbs new file mode 100644 index 00000000000..5991a7287e9 --- /dev/null +++ b/plugins/chat/assets/javascripts/discourse/components/chat/composer/separator.hbs @@ -0,0 +1 @@ +
\ No newline at end of file diff --git a/plugins/chat/assets/javascripts/discourse/components/chat/composer/separator.js b/plugins/chat/assets/javascripts/discourse/components/chat/composer/separator.js new file mode 100644 index 00000000000..47b899f4625 --- /dev/null +++ b/plugins/chat/assets/javascripts/discourse/components/chat/composer/separator.js @@ -0,0 +1,3 @@ +import Component from "@glimmer/component"; + +export default class ChatComposerSeparator extends Component {} diff --git a/plugins/chat/assets/javascripts/discourse/initializers/chat-setup.js b/plugins/chat/assets/javascripts/discourse/initializers/chat-setup.js index a23082bcbb0..5acabfedb7c 100644 --- a/plugins/chat/assets/javascripts/discourse/initializers/chat-setup.js +++ b/plugins/chat/assets/javascripts/discourse/initializers/chat-setup.js @@ -18,6 +18,7 @@ export default { initialize(container) { this.chatService = container.lookup("service:chat"); + this.site = container.lookup("service:site"); this.siteSettings = container.lookup("service:site-settings"); this.appEvents = container.lookup("service:app-events"); this.appEvents.on("discourse:focus-changed", this, "_handleFocusChanged"); @@ -58,8 +59,8 @@ export default { label: "chat.emoji", id: "emoji", class: "chat-emoji-btn", - icon: "discourse-emojis", - position: "dropdown", + icon: "far-smile", + position: this.site.desktopView ? "inline" : "dropdown", context: "channel", action() { const chatEmojiPickerManager = container.lookup( diff --git a/plugins/chat/assets/stylesheets/common/chat-composer-button.scss b/plugins/chat/assets/stylesheets/common/chat-composer-button.scss index 9e6c9528775..c390bcc017c 100644 --- a/plugins/chat/assets/stylesheets/common/chat-composer-button.scss +++ b/plugins/chat/assets/stylesheets/common/chat-composer-button.scss @@ -8,7 +8,7 @@ box-sizing: border-box; width: 50px; border: 0; - height: 100%; + height: 50px; background: none; } } diff --git a/plugins/chat/assets/stylesheets/common/chat-composer-inline-button.scss b/plugins/chat/assets/stylesheets/common/chat-composer-inline-button.scss deleted file mode 100644 index e1b019a3154..00000000000 --- a/plugins/chat/assets/stylesheets/common/chat-composer-inline-button.scss +++ /dev/null @@ -1,9 +0,0 @@ -.chat-composer-inline-button { - border-radius: 6px; - width: 32px; - height: 32px; - - & + .chat-composer-inline-button { - margin-left: 0.25rem; - } -} diff --git a/plugins/chat/assets/stylesheets/common/chat-composer-separator.scss b/plugins/chat/assets/stylesheets/common/chat-composer-separator.scss new file mode 100644 index 00000000000..657e01aef32 --- /dev/null +++ b/plugins/chat/assets/stylesheets/common/chat-composer-separator.scss @@ -0,0 +1,8 @@ +.chat-composer-separator { + width: 1px; + margin: 10px 0.25rem; + box-sizing: border-box; + background: var(--primary-low-mid); + height: 30px; + display: flex; +} diff --git a/plugins/chat/assets/stylesheets/common/chat-composer.scss b/plugins/chat/assets/stylesheets/common/chat-composer.scss index 28716c7f98e..fff091fd009 100644 --- a/plugins/chat/assets/stylesheets/common/chat-composer.scss +++ b/plugins/chat/assets/stylesheets/common/chat-composer.scss @@ -4,7 +4,7 @@ flex-direction: column; z-index: 3; background-color: var(--primary-very-low); - padding: 12px 10px env(safe-area-inset-bottom) 10px; + padding: 0.5rem 0 env(safe-area-inset-bottom) 0; .keyboard-visible & { padding-bottom: 0; @@ -22,7 +22,7 @@ .chat-composer-button, .chat-composer-separator { - align-self: stretch; + align-self: flex-end; } &__outer-container { @@ -30,6 +30,19 @@ align-items: center; box-sizing: border-box; width: 100%; + padding-inline: 1rem; + } + + &__inline-button { + .d-icon { + color: var(--primary-medium); + } + + &:hover { + .d-icon { + color: var(--primary); + } + } } &__inner-container { @@ -85,6 +98,7 @@ .d-icon { background: none !important; + color: var(--primary); } .chat-composer.is-send-enabled & { @@ -122,10 +136,6 @@ background: none !important; } } - - .d-icon { - color: var(--primary); - } } &__input-container { @@ -136,6 +146,11 @@ align-self: stretch; } + --100dvh: 100vh; + @supports (height: 100dvh) { + --100dvh: 100dvh; + } + &__input { overflow-x: hidden; width: 100%; @@ -143,13 +158,17 @@ outline: none; border: 0; resize: none; - max-height: 125px; + max-height: calc( + ( + var(--100dvh) - var(--header-offset, 0px) - + var(--chat-header-offset, 0px) + ) / 100 * 25 + ); background: none; - margin: 0; padding: 0; + margin: 5px 0; text-overflow: ellipsis; cursor: inherit; - @include chat-scrollbar(); &[disabled] { diff --git a/plugins/chat/assets/stylesheets/common/index.scss b/plugins/chat/assets/stylesheets/common/index.scss index ec538d9b1b1..e71c7f1c21a 100644 --- a/plugins/chat/assets/stylesheets/common/index.scss +++ b/plugins/chat/assets/stylesheets/common/index.scss @@ -10,7 +10,6 @@ @import "chat-channel-settings-saved-indicator"; @import "chat-channel-title"; @import "chat-composer-dropdown"; -@import "chat-composer-inline-button"; @import "chat-composer-upload"; @import "chat-composer-uploads"; @import "chat-composer"; @@ -52,3 +51,4 @@ @import "chat-thread-list-item"; @import "chat-threads-list"; @import "chat-thread-original-message"; +@import "chat-composer-separator"; diff --git a/plugins/chat/assets/stylesheets/desktop/base-desktop.scss b/plugins/chat/assets/stylesheets/desktop/base-desktop.scss index 121e85ab6e5..636874b0986 100644 --- a/plugins/chat/assets/stylesheets/desktop/base-desktop.scss +++ b/plugins/chat/assets/stylesheets/desktop/base-desktop.scss @@ -35,7 +35,7 @@ } .chat-message:not(.user-info-hidden) { - padding: 0.65em 1em 0.15em; + padding: 0.65rem 1rem 0.15rem; } .chat-message-text { @@ -52,7 +52,7 @@ } .chat-message.user-info-hidden { - padding: 0.15em 1em; + padding: 0.15rem 1rem; .chat-time { color: var(--secondary-medium); diff --git a/plugins/chat/spec/system/chat_composer_spec.rb b/plugins/chat/spec/system/chat_composer_spec.rb index 1412d2d085f..a505b59ccc6 100644 --- a/plugins/chat/spec/system/chat_composer_spec.rb +++ b/plugins/chat/spec/system/chat_composer_spec.rb @@ -192,8 +192,7 @@ RSpec.describe "Chat composer", type: :system, js: true do SiteSetting.emoji_deny_list = "monkey|peach" chat.visit_channel(channel_1) - channel.open_action_menu - channel.click_action_button("emoji") + channel.composer.open_emoji_picker expect(page).to have_no_selector("[data-emoji='monkey']") expect(page).to have_no_selector("[data-emoji='peach']") diff --git a/plugins/chat/spec/system/message_notifications_mobile_spec.rb b/plugins/chat/spec/system/message_notifications_mobile_spec.rb index c2dbb806b70..54184a8fdd7 100644 --- a/plugins/chat/spec/system/message_notifications_mobile_spec.rb +++ b/plugins/chat/spec/system/message_notifications_mobile_spec.rb @@ -158,6 +158,7 @@ RSpec.describe "Message notifications - mobile", type: :system, js: true, mobile expect(page).to have_css(".chat-header-icon .chat-channel-unread-indicator", text: "1") expect(page).to have_css( ".chat-channel-row[data-chat-channel-id=\"#{dm_channel_1.id}\"] .chat-channel-unread-indicator", + wait: 25, ) using_session(:user_1) do |session| @@ -165,7 +166,11 @@ RSpec.describe "Message notifications - mobile", type: :system, js: true, mobile session.quit end - expect(page).to have_css(".chat-header-icon .chat-channel-unread-indicator", text: "2") + expect(page).to have_css( + ".chat-header-icon .chat-channel-unread-indicator", + text: "2", + wait: 25, + ) end it "reorders channels" do diff --git a/plugins/chat/spec/system/navigating_to_message_spec.rb b/plugins/chat/spec/system/navigating_to_message_spec.rb deleted file mode 100644 index c8a40988e89..00000000000 --- a/plugins/chat/spec/system/navigating_to_message_spec.rb +++ /dev/null @@ -1,172 +0,0 @@ -# frozen_string_literal: true - -RSpec.describe "Navigating to message", type: :system, js: true do - fab!(:current_user) { Fabricate(:user) } - fab!(:channel_1) { Fabricate(:category_channel) } - fab!(:first_message) { Fabricate(:chat_message, chat_channel: channel_1) } - - let(:chat_page) { PageObjects::Pages::Chat.new } - let(:chat_drawer_page) { PageObjects::Pages::ChatDrawer.new } - let(:link) { "My favorite message" } - - before do - chat_system_bootstrap - channel_1.add(current_user) - 75.times { Fabricate(:chat_message, chat_channel: channel_1) } - sign_in(current_user) - end - - context "when in full page mode" do - before { chat_page.prefers_full_page } - - context "when clicking a link containing a message id" do - fab!(:topic_1) { Fabricate(:topic) } - - before do - Fabricate( - :post, - topic: topic_1, - raw: "#{link}", - ) - end - - it "highlights the correct message" do - visit("/t/-/#{topic_1.id}") - click_link(link) - - expect(page).to have_css( - ".chat-message-container.highlighted[data-id='#{first_message.id}']", - ) - end - end - - context "when clicking a link to a message from the current channel" do - before do - Fabricate( - :chat_message, - chat_channel: channel_1, - message: "[#{link}](/chat/c/-/#{channel_1.id}/#{first_message.id})", - ) - end - - it "highlights the correct message" do - chat_page.visit_channel(channel_1) - click_link(link) - - expect(page).to have_css( - ".chat-message-container.highlighted[data-id='#{first_message.id}']", - ) - end - - it "highlights the correct message after using the bottom arrow" do - chat_page.visit_channel(channel_1) - - click_link(link) - - expect(page).to have_css( - ".chat-message-container.highlighted[data-id='#{first_message.id}']", - ) - - click_button(class: "chat-scroll-to-bottom") - - expect(page).to have_content(link) - - click_link(link) - - expect(page).to have_css( - ".chat-message-container.highlighted[data-id='#{first_message.id}']", - ) - end - end - - context "when clicking a link to a message from another channel" do - fab!(:channel_2) { Fabricate(:category_channel) } - - before do - Fabricate( - :chat_message, - chat_channel: channel_2, - message: "[#{link}](/chat/c/-/#{channel_1.id}/#{first_message.id})", - ) - channel_2.add(current_user) - end - - it "highlights the correct message" do - chat_page.visit_channel(channel_2) - click_link(link) - - expect(page).to have_css( - ".chat-message-container.highlighted[data-id='#{first_message.id}']", - ) - end - end - - context "when navigating directly to a message link" do - it "highglights the correct message" do - visit("/chat/c/-/#{channel_1.id}/#{first_message.id}") - - expect(page).to have_css( - ".chat-message-container.highlighted[data-id='#{first_message.id}']", - ) - end - end - end - - context "when in drawer" do - context "when clicking a link containing a message id" do - fab!(:topic_1) { Fabricate(:topic) } - - before do - Fabricate( - :post, - topic: topic_1, - raw: "#{link}", - ) - end - - it "highlights correct message" do - visit("/t/-/#{topic_1.id}") - click_link(link) - - expect(page).to have_css( - ".chat-drawer.is-expanded .chat-message-container.highlighted[data-id='#{first_message.id}']", - ) - end - end - - context "when clicking a link to a message from the current channel" do - before do - Fabricate( - :chat_message, - chat_channel: channel_1, - message: "[#{link}](/chat/c/-/#{channel_1.id}/#{first_message.id})", - ) - end - - it "highlights the correct message" do - visit("/") - chat_page.open_from_header - chat_drawer_page.open_channel(channel_1) - click_link(link) - - expect(page).to have_css( - ".chat-message-container.highlighted[data-id='#{first_message.id}']", - ) - end - - it "highlights the correct message after using the bottom arrow" do - visit("/") - chat_page.open_from_header - chat_drawer_page.open_channel(channel_1) - - click_link(link) - click_button(class: "chat-scroll-to-bottom") - click_link(link) - - expect(page).to have_css( - ".chat-message-container.highlighted[data-id='#{first_message.id}']", - ) - end - end - end -end diff --git a/plugins/chat/spec/system/page_objects/chat/chat_channel.rb b/plugins/chat/spec/system/page_objects/chat/chat_channel.rb index ecf74ce4bb6..b041bc6c110 100644 --- a/plugins/chat/spec/system/page_objects/chat/chat_channel.rb +++ b/plugins/chat/spec/system/page_objects/chat/chat_channel.rb @@ -3,6 +3,10 @@ module PageObjects module Pages class ChatChannel < PageObjects::Pages::Base + def composer + @composer ||= PageObjects::Components::Chat::Composer.new(".chat-channel") + end + def replying_to?(message) find(".chat-channel .chat-reply", text: message.message) end diff --git a/plugins/chat/spec/system/page_objects/chat/components/composer.rb b/plugins/chat/spec/system/page_objects/chat/components/composer.rb index 98fe8fc8225..bba098582ac 100644 --- a/plugins/chat/spec/system/page_objects/chat/components/composer.rb +++ b/plugins/chat/spec/system/page_objects/chat/components/composer.rb @@ -27,6 +27,10 @@ module PageObjects def edit_last_message_shortcut input.send_keys(%i[arrow_up]) end + + def open_emoji_picker + find(context).find(SELECTOR).find(".chat-composer-button__btn.emoji").click + end end end end diff --git a/plugins/chat/test/javascripts/components/chat-composer-inline-buttons-test.js b/plugins/chat/test/javascripts/components/chat-composer-inline-buttons-test.js deleted file mode 100644 index 3933a396a28..00000000000 --- a/plugins/chat/test/javascripts/components/chat-composer-inline-buttons-test.js +++ /dev/null @@ -1,23 +0,0 @@ -import { setupRenderingTest } from "discourse/tests/helpers/component-test"; -import { exists } from "discourse/tests/helpers/qunit-helpers"; -import hbs from "htmlbars-inline-precompile"; -import { module, test } from "qunit"; -import { render } from "@ember/test-helpers"; - -module( - "Discourse Chat | Component | chat-composer-inline-buttons", - function (hooks) { - setupRenderingTest(hooks); - - test("buttons", async function (assert) { - this.set("buttons", [{ id: "foo", icon: "times", action: () => {} }]); - - await render( - hbs`` - ); - - assert.true(exists(".chat-composer-inline-button.foo")); - assert.true(exists(".chat-composer-inline-button.foo .d-icon-times")); - }); - } -);