From 545a6907a9c0695ca23c6090eea9581f46977328 Mon Sep 17 00:00:00 2001 From: Praise Freedom Dike <70984186+freedompraise@users.noreply.github.com> Date: Mon, 9 Sep 2024 10:03:50 +0100 Subject: [PATCH] Update chatbox design and add send icon SVG file (#461) * feat: Add send icon SVG file * chore: Update chatbox header and footer design * feat: Update chatbox design and add send icon SVG file * fix: Adjust position of video overlay to left side * chore: Adjust position of chatbox and update CSS styles * chore: Update chatbox header to display user's name * chore: Update chatbox header and footer design * Add close-icon.svg file * refactor: Improve chatbox textarea resizing This commit improves the resizing behavior of the chatbox textarea. Previously, the textarea would resize vertically as the user typed, but it would not reset to its original height after sending a message. This commit fixes that issue by resetting the height of the textarea to "auto" after sending a message. Co-authored-by: John Solly <9572232+jsolly@users.noreply.github.com> * refactor: Increase chatbox height for better user experience This commit increases the height of the chatbox in the main.css file to improve the user experience. The chatbox height was increased from 500px to 550px to provide more space for messages. This change ensures that users have enough room to view and interact with the chatbox comfortably. Co-authored-by: John Solly <9572232+jsolly@users.noreply.github.com> * refactor: Update chatbox UI for better user experience * refactor: Update chatbox UI for better user experience * reduce textarea font size to 0.9em * refactor: Update chatbox UI for better user experience * refactor: Update chatbox UI for better user experience * refactor: Update chatbox UI for better user experience * Add styling for close button in chatbox header. * refactor: Update chatbox UI for better user experience * refactor: Adjust opacity of textarea placeholder in main.css This commit adjusts the opacity of the textarea placeholder in the main.css file. The opacity was changed from 0 to 0.3 to provide a subtle hint to the user that the textarea is a placeholder. This change improves the user experience by making the placeholder text more visible. Co-authored-by: John Solly <9572232+jsolly@users.noreply.github.com> * refactor: Update chatbox UI for better user experience --------- Co-authored-by: John Solly <9572232+jsolly@users.noreply.github.com> --- app/blog/templates/blog/parts/chatbox.html | 51 ++++- app/staticfiles/css/main.css | 250 ++++++++++++--------- app/staticfiles/js/chatbox.js | 34 ++- app/staticfiles/svg/close-icon.svg | 4 + app/staticfiles/svg/send-icon.svg | 5 + 5 files changed, 221 insertions(+), 123 deletions(-) create mode 100644 app/staticfiles/svg/close-icon.svg create mode 100644 app/staticfiles/svg/send-icon.svg diff --git a/app/blog/templates/blog/parts/chatbox.html b/app/blog/templates/blog/parts/chatbox.html index cf627e56e..05b062dfc 100644 --- a/app/blog/templates/blog/parts/chatbox.html +++ b/app/blog/templates/blog/parts/chatbox.html @@ -7,27 +7,54 @@ Ezra's avatar
-

Ask a Question

-

Hi, I'm Ezra! I can answer questions about any blog post on - this site!

+

Ezra

+

{% now "jS F Y" %}

+
+ +
+ +
+
I can answer questions about any blog post on this + site!
+
Hi, I'm Ezra!
-
+
- +
\ No newline at end of file diff --git a/app/staticfiles/css/main.css b/app/staticfiles/css/main.css index b40e5fb74..d6815a35b 100644 --- a/app/staticfiles/css/main.css +++ b/app/staticfiles/css/main.css @@ -44,9 +44,11 @@ Global Styles --primary-box-shadow: 0px 10px 15px rgba(0, 0, 0, 0.1); --secondary-box-shadow: 0px -10px 15px rgba(0, 0, 0, 0.1); --primary-gradient: linear-gradient(93.12deg, #0d6efd 0.52%, #007bff 100%); - --secondary-gradient: linear-gradient(268.91deg, - #0d6efd -2.14%, - #007bff 99.69%); + --secondary-gradient: linear-gradient( + 268.91deg, + #0d6efd -2.14%, + #007bff 99.69% + ); } html { @@ -599,7 +601,6 @@ figure { margin-right: 0.5rem; } - /* Post Submit Button */ .post-submit-button { display: inline-block; @@ -775,14 +776,11 @@ figure img { height: auto; } - - - /* ============= Typography ============= */ -p>code { +p > code { color: #e76f51; font-family: monospace; font-size: 0.95em; @@ -847,26 +845,28 @@ h2 { margin-bottom: 0.5em; } -:is(h1, - h2, - h3, - h4, - h5, - h6, - strong, - .list-group-item, - svg, - table, - p, - blockquote, - li, - legend, - small, - .word-count, - label, - input, - form, -) { +:is( + h1, + h2, + h3, + h4, + h5, + h6, + strong, + .list-group-item, + svg, + table, + p, + blockquote, + li, + legend, + small, + .word-count, + label, + input, + form, + + ) { color: var(--secondary-color); } @@ -875,7 +875,7 @@ hr { opacity: 0.25; } -.post-content>p:first-of-type::first-letter { +.post-content > p:first-of-type::first-letter { font-size: 2rem; font-weight: 700; } @@ -921,75 +921,99 @@ button a, button a:hover { color: inherit; } +/* ============= Chatbot ============= */ -/* ============= - Chatbot -============= */ +#chatbox-container button svg { + transition: fill 0.3s ease; +} + +#chatbox-container button:hover svg path { + fill: white !important; +} + +#chatbox-container button:hover, +#chatbox-container button { + background-color: transparent !important; +} #chatbox-icon { - width: 35px; - height: 35px; + width: 40px; + height: 40px; + cursor: pointer; } #chatbot-container { position: fixed; - bottom: 0; - right: 0; + bottom: 20px; + right: 20px; margin: 10px; } .chatbox { position: fixed; - bottom: 30px; - left: 20px; + bottom: 20px; + right: 20px; z-index: 123456; } -/* CONTENT IS CLOSED */ .chatbox__support { display: none; flex-direction: column; - background: #eee; - width: 300px; - height: 350px; + background: #f9f9f9; + width: 350px; + height: 550px; + border-radius: 10px; + box-shadow: 0 5px 15px rgba(0, 0, 0, 0.2); + overflow: hidden; +} + +.chatbox__time--header { + font-size: 0.6em; + color: white; + margin-top: 1px; } /* CONTENT IS OPEN */ .chatbox--active { display: flex; - transform: translateY(-40px); + transform: translateY(-20px); z-index: 123456; } .send__button { - padding: 6px; - background: transparent; - border: none; - outline: none; + cursor: pointer; + flex: 0 0 auto; } .send__button:hover { - background-color: transparent; - color: black; + size: 1.1rem; } /* MESSAGES */ textarea { - background-color: var(--primary-color); - color: var(--secondary-color); + background-color: #ffffff; + color: #333333; resize: none; + border-radius: 10px; + padding: 10px; + border: 1px solid #ddd; + font-family: "Arial", sans-serif; + font-size: 0.9rem; } textarea::placeholder { - color: var(--secondary-color); + color: #999999; } .chatbox__messages { margin-top: auto; display: flex; - overflow-y: scroll; + overflow-y: auto; flex-direction: column-reverse; - color: var(--secondary-color); + color: #333333; + padding: 20px; + height: 400px; + background: #f5f5f5; } .messages__item--user { @@ -1001,25 +1025,24 @@ textarea::placeholder { } .chatbox__support { - background: var(--primary-color); - height: 500px; - width: 350px; + background: #f5f5f5; + height: 550px; + width: 400px; box-shadow: 0px 0px 15px rgba(0, 0, 0, 0.1); - border-top-left-radius: 20px; - border-top-right-radius: 20px; + border-radius: 10px; } /* HEADER */ .chatbox__header { - background: var(--primary-gradient); + background: linear-gradient(135deg, #0d6efd, #0a58ca); display: flex; flex-direction: row; align-items: center; - justify-content: center; + justify-content: space-between; padding: 15px 20px; - border-top-left-radius: 20px; - border-top-right-radius: 20px; - box-shadow: var(--primary-box-shadow); + border-top-left-radius: 10px; + border-top-right-radius: 10px; + box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); } .chatbox__image--header { @@ -1029,6 +1052,7 @@ textarea::placeholder { .chatbox__heading--header { font-size: 1.2rem; color: white; + margin-bottom: 0; } .chatbox__description--header { @@ -1038,7 +1062,7 @@ textarea::placeholder { /* Messages */ .chatbox__messages { - padding: 0 20px; + padding: 20px; } .messages__item { @@ -1046,6 +1070,9 @@ textarea::placeholder { background: #e6e6e8; padding: 8px 12px; max-width: 70%; + border-radius: 10px; + box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); + position: relative; } .messages__item--bot { @@ -1063,30 +1090,46 @@ textarea::placeholder { color: white; } +.messages__item::after { + content: attr(data-time); + position: absolute; + bottom: -20px; + right: 10px; + font-size: 0.75rem; + color: #888; + opacity: 0.3; + transition: opacity 0.3s; +} + +.messages__item:hover::after { + opacity: 1; +} + /* FOOTER */ .chatbox__footer { display: flex; flex-direction: row; align-items: center; - justify-content: space-between; - padding: 20px 20px; - background: var(--secondary-gradient); - box-shadow: var(--secondary-box-shadow); - margin-top: 20px; + padding: 10px 20px; + background: linear-gradient(135deg, #0a58ca, #0d6efd); + box-shadow: 0 -4px 8px rgba(0, 0, 0, 0.1); + border-bottom-left-radius: 10px; + border-bottom-right-radius: 10px; +} + +.chatbox__input-container { + display: flex; + width: 380px; } .chatbox__footer textarea { - width: 80%; + width: 90%; border: none; padding: 10px 10px; - border-radius: 30px; + border-radius: 10px; text-align: left; } -.chatbox__send--footer { - color: white; -} - .chatbox__button button, .chatbox__button button:focus, .chatbox__button button:visited { @@ -1094,20 +1137,34 @@ textarea::placeholder { background: white; border: none; outline: none; - border-top-left-radius: 50px; - border-top-right-radius: 50px; - border-bottom-left-radius: 50px; + border-radius: 50px; box-shadow: 0px 10px 15px rgba(0, 0, 0, 0.1); cursor: pointer; } -#chatbox-submit { - display: inline-flex; +.chatbox__close--header { + margin-left: auto; } -#question-text-area { - margin-right: 10px; +.chatbox__close--header button { + border: none; + border-radius: 50%; + padding: 5px; + cursor: pointer; } + +.chatbox__footer--small { + font-size: 0.7rem; + text-align: center; + padding: 5px; + background: #f5f5f5; +} + +.chatbox__footer--small a { + color: #0d6efd; + text-decoration: none; +} + /* ============= Comments ============= */ @@ -1116,12 +1173,10 @@ textarea::placeholder { list-style-type: none; } - .comment-delete-form { display: inline; } - .comment-btn { padding: 3px 8px; font-size: 8px; @@ -1132,9 +1187,7 @@ textarea::placeholder { box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); padding: 1rem; margin-bottom: 1rem; -} - - +} /* ============= Status Page @@ -1172,7 +1225,7 @@ textarea::placeholder { ============= */ /* Override Ckeditor */ -.ck.ck-toolbar.ck-toolbar_grouping>.ck-toolbar__items { +.ck.ck-toolbar.ck-toolbar_grouping > .ck-toolbar__items { flex-wrap: wrap !important; } @@ -1185,7 +1238,7 @@ iframe { } code { - padding: 1rem !important + padding: 1rem !important; } #draft { @@ -1207,7 +1260,7 @@ video { color: var(--a11-red); position: fixed; bottom: 20px; - right: 20px; + left: 20px; z-index: 999; font-size: 2rem; } @@ -1239,7 +1292,7 @@ video { Media Queries ============= */ @media (prefers-reduced-motion: reduce) { - .navbar-nav>li:hover:not(.dropdown) { + .navbar-nav > li:hover:not(.dropdown) { animation: none; } @@ -1285,7 +1338,7 @@ video { fill: black; } - p>code { + p > code { color: #a626a4; } @@ -1333,7 +1386,6 @@ video { } @media print { - /* @page { size: Letter portrait; @@ -1395,13 +1447,10 @@ video { #aboutMe { display: none !important; } - - } /* Responsive Styles*/ @media (max-width: 1239px) { - /* Changes the layout of the container to a single column grid with the header, sidebar, post-content, and footer taking up @@ -1447,7 +1496,6 @@ video { max-width: 100%; } - .post-card-meta-img-container img { display: block; width: 100%; @@ -1507,7 +1555,6 @@ video { } @media screen and (min-width: 1240px) { - /* Changes the layout of the container to a 4 column grid. The Sidebar and post-content occupy the middle two columns, @@ -1551,7 +1598,6 @@ video { .post-content { grid-column: 3; } - } @media screen and (min-width: 2000px) { @@ -1583,10 +1629,10 @@ video { } @media (min-width: 992px) { - .navbar-nav>li:hover:not(.dropdown) { + .navbar-nav > li:hover:not(.dropdown) { animation: button-shake 0.3s linear; } .nav-categories { display: none; } -} \ No newline at end of file +} diff --git a/app/staticfiles/js/chatbox.js b/app/staticfiles/js/chatbox.js index 9bd02f6f8..c7a736474 100644 --- a/app/staticfiles/js/chatbox.js +++ b/app/staticfiles/js/chatbox.js @@ -4,31 +4,46 @@ document.addEventListener("DOMContentLoaded", () => { this.openButton = document.querySelector(".chatbox__button"); this.chatBox = document.querySelector(".chatbox__support"); this.sendButton = document.querySelector(".send__button"); + this.closeButton = document.querySelector( + ".chatbox__close--header button" + ); this.state = false; } display() { this.openButton.addEventListener("click", () => this.toggleState()); + this.closeButton.addEventListener("click", () => this.toggleState()); this.sendButton.addEventListener("click", () => this.onSendButton()); + const textArea = this.chatBox.querySelector("textarea"); - const node = this.chatBox.querySelector("textarea"); - node.addEventListener("input", () => { - node.style.height = "auto"; - node.style.height = `${node.scrollHeight}px`; + textArea.addEventListener("input", () => { + textArea.style.height = "auto"; + textArea.style.height = `${textArea.scrollHeight}px`; }); - node.addEventListener("keyup", ({ key, shiftKey }) => { + textArea.addEventListener("keyup", ({ key, shiftKey }) => { if (key === "Enter" && !shiftKey) { this.onSendButton(); } }); + + const observer = new MutationObserver(() => { + textArea.style.height = "auto"; + }); + + observer.observe(textArea, { + childList: true, + subtree: true, + characterData: true, + }); } toggleState() { this.state = !this.state; - - // show or hides the box this.chatBox.classList.toggle("chatbox--active", this.state); + document.getElementById("chatbox-icon").style.display = this.state + ? "none" + : "block"; } onSendButton() { @@ -37,8 +52,10 @@ document.addEventListener("DOMContentLoaded", () => { if (text === "" || text === "\n") { return; } - this.updateChatText(text); + textField.value = ""; + textField.style.height = "auto"; + textField.dispatchEvent(new Event("input")); } updateChatText(text) { @@ -47,7 +64,6 @@ document.addEventListener("DOMContentLoaded", () => { message.classList.add("messages__item", "messages__item--user"); message.textContent = text; chatmessages.prepend(message); - this.chatBox.querySelector("#question-text-area").value = ""; } } diff --git a/app/staticfiles/svg/close-icon.svg b/app/staticfiles/svg/close-icon.svg new file mode 100644 index 000000000..cb0bf60a5 --- /dev/null +++ b/app/staticfiles/svg/close-icon.svg @@ -0,0 +1,4 @@ + + + + diff --git a/app/staticfiles/svg/send-icon.svg b/app/staticfiles/svg/send-icon.svg new file mode 100644 index 000000000..f6b0ad5f0 --- /dev/null +++ b/app/staticfiles/svg/send-icon.svg @@ -0,0 +1,5 @@ + + + + +