From 503efaf10bd876a082e62920cc48f984ad06bdfe Mon Sep 17 00:00:00 2001 From: Joao P Dubas Date: Wed, 6 Nov 2024 00:55:03 +0000 Subject: [PATCH] feat(chat): usage improvements with hooks 1. scroll room messages to the bottom 2. submit message on `enter` --- assets/js/app.js | 8 ++++++++ assets/js/hooks/ChatMessageTextarea.js | 14 ++++++++++++++ assets/js/hooks/RoomMessages.js | 10 ++++++++++ lib/slax_web/live/chat_room_live.ex | 18 +++++++++++++++--- 4 files changed, 47 insertions(+), 3 deletions(-) create mode 100644 assets/js/hooks/ChatMessageTextarea.js create mode 100644 assets/js/hooks/RoomMessages.js diff --git a/assets/js/app.js b/assets/js/app.js index 492550a..5228a3f 100644 --- a/assets/js/app.js +++ b/assets/js/app.js @@ -21,9 +21,17 @@ import "phoenix_html" import { Socket } from "phoenix" import { LiveSocket } from "phoenix_live_view" import topbar from "../vendor/topbar" +import RoomMessages from "./hooks/RoomMessages" +import ChatMessageTextarea from "./hooks/ChatMessageTextarea" + +const hooks = { + ChatMessageTextarea, + RoomMessages, +} let csrfToken = document.querySelector("meta[name='csrf-token']").getAttribute("content") let liveSocket = new LiveSocket("/live", Socket, { + hooks, longPollFallbackMs: 2500, params: { _csrf_token: csrfToken, diff --git a/assets/js/hooks/ChatMessageTextarea.js b/assets/js/hooks/ChatMessageTextarea.js new file mode 100644 index 0000000..87e1491 --- /dev/null +++ b/assets/js/hooks/ChatMessageTextarea.js @@ -0,0 +1,14 @@ +const ChatMessageTextarea = { + mounted() { + this.el.addEventListener('keydown', e => { + if (e.key == 'Enter' && !e.shitfKey) { + const form = document.getElementById('new-message-form'); + + form.dispatchEvent(new Event('change', { bubbles: true, cancelable: true })); + form.dispatchEvent(new Event('submit', { bubbles: true, cancelable: true })); + } + }); + } +}; + +export default ChatMessageTextarea; diff --git a/assets/js/hooks/RoomMessages.js b/assets/js/hooks/RoomMessages.js new file mode 100644 index 0000000..685c048 --- /dev/null +++ b/assets/js/hooks/RoomMessages.js @@ -0,0 +1,10 @@ +const RoomMessages = { + mounted() { + this.el.scrollTop = this.el.scrollHeight; + this.handleEvent("scroll_messages_to_bottom", () => { + this.el.scrollTop = this.el.scrollHeight; + }); + } +}; + +export default RoomMessages; diff --git a/lib/slax_web/live/chat_room_live.ex b/lib/slax_web/live/chat_room_live.ex index 67c3e57..9416f81 100644 --- a/lib/slax_web/live/chat_room_live.ex +++ b/lib/slax_web/live/chat_room_live.ex @@ -89,7 +89,12 @@ defmodule SlaxWeb.ChatRoomLive do <% end %> -
+
<.message :for={{dom_id, message} <- @streams.messages} current_user={@current_user} @@ -113,6 +118,7 @@ defmodule SlaxWeb.ChatRoomLive do name={@new_message_form[:body].name} placeholder={"Message ##{@room.name}"} phx-debounce + phx-hook="ChatMessageTextarea" rows="1" ><%= Phoenix.HTML.Form.normalize_value("textarea", @new_message_form[:body].value) %>