294 lines
16 KiB
HTML
294 lines
16 KiB
HTML
|
|
<style>
|
||
|
|
:root {
|
||
|
|
--body-bg: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
|
||
|
|
--msger-bg: #fff;
|
||
|
|
--border: 2px solid #ddd;
|
||
|
|
--left-msg-bg: #ececec;
|
||
|
|
--right-msg-bg: #579ffb;
|
||
|
|
}
|
||
|
|
|
||
|
|
html {
|
||
|
|
box-sizing: border-box;
|
||
|
|
}
|
||
|
|
|
||
|
|
*,
|
||
|
|
*:before,
|
||
|
|
*:after {
|
||
|
|
margin: 0;
|
||
|
|
padding: 0;
|
||
|
|
box-sizing: inherit;
|
||
|
|
}
|
||
|
|
|
||
|
|
body {
|
||
|
|
display: flex;
|
||
|
|
justify-content: center;
|
||
|
|
align-items: center;
|
||
|
|
height: 100vh;
|
||
|
|
background-image: var(--body-bg);
|
||
|
|
font-family: Helvetica, sans-serif;
|
||
|
|
}
|
||
|
|
|
||
|
|
.msger {
|
||
|
|
display: flex;
|
||
|
|
flex-flow: column wrap;
|
||
|
|
justify-content: space-between;
|
||
|
|
width: 100%;
|
||
|
|
max-width: 867px;
|
||
|
|
margin: 25px 10px;
|
||
|
|
height: calc(100% - 50px);
|
||
|
|
border: var(--border);
|
||
|
|
border-radius: 5px;
|
||
|
|
background: var(--msger-bg);
|
||
|
|
box-shadow: 0 15px 15px -5px rgba(0, 0, 0, 0.2);
|
||
|
|
}
|
||
|
|
|
||
|
|
.msger-header {
|
||
|
|
display: flex;
|
||
|
|
justify-content: space-between;
|
||
|
|
padding: 10px;
|
||
|
|
border-bottom: var(--border);
|
||
|
|
background: #eee;
|
||
|
|
color: #666;
|
||
|
|
}
|
||
|
|
|
||
|
|
.msger-chat {
|
||
|
|
flex: 1;
|
||
|
|
overflow-y: auto;
|
||
|
|
padding: 10px;
|
||
|
|
}
|
||
|
|
.msger-chat::-webkit-scrollbar {
|
||
|
|
width: 6px;
|
||
|
|
}
|
||
|
|
.msger-chat::-webkit-scrollbar-track {
|
||
|
|
background: #ddd;
|
||
|
|
}
|
||
|
|
.msger-chat::-webkit-scrollbar-thumb {
|
||
|
|
background: #bdbdbd;
|
||
|
|
}
|
||
|
|
.msg {
|
||
|
|
display: flex;
|
||
|
|
align-items: flex-end;
|
||
|
|
margin-bottom: 10px;
|
||
|
|
}
|
||
|
|
.msg:last-of-type {
|
||
|
|
margin: 0;
|
||
|
|
}
|
||
|
|
.msg-img {
|
||
|
|
width: 50px;
|
||
|
|
height: 50px;
|
||
|
|
margin-right: 10px;
|
||
|
|
background: #ddd;
|
||
|
|
background-repeat: no-repeat;
|
||
|
|
background-position: center;
|
||
|
|
background-size: cover;
|
||
|
|
border-radius: 50%;
|
||
|
|
}
|
||
|
|
.msg-bubble {
|
||
|
|
max-width: 450px;
|
||
|
|
padding: 15px;
|
||
|
|
border-radius: 15px;
|
||
|
|
background: var(--left-msg-bg);
|
||
|
|
}
|
||
|
|
.msg-info {
|
||
|
|
display: flex;
|
||
|
|
justify-content: space-between;
|
||
|
|
align-items: center;
|
||
|
|
margin-bottom: 10px;
|
||
|
|
}
|
||
|
|
.msg-info-name {
|
||
|
|
margin-right: 10px;
|
||
|
|
font-weight: bold;
|
||
|
|
}
|
||
|
|
.msg-info-time {
|
||
|
|
font-size: 0.85em;
|
||
|
|
}
|
||
|
|
|
||
|
|
.left-msg .msg-bubble {
|
||
|
|
border-bottom-left-radius: 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
.right-msg {
|
||
|
|
flex-direction: row-reverse;
|
||
|
|
}
|
||
|
|
.right-msg .msg-bubble {
|
||
|
|
background: var(--right-msg-bg);
|
||
|
|
color: #fff;
|
||
|
|
border-bottom-right-radius: 0;
|
||
|
|
}
|
||
|
|
.right-msg .msg-img {
|
||
|
|
margin: 0 0 0 10px;
|
||
|
|
}
|
||
|
|
|
||
|
|
.msger-inputarea {
|
||
|
|
display: flex;
|
||
|
|
padding: 10px;
|
||
|
|
border-top: var(--border);
|
||
|
|
background: #eee;
|
||
|
|
}
|
||
|
|
.msger-inputarea * {
|
||
|
|
padding: 10px;
|
||
|
|
border: none;
|
||
|
|
border-radius: 3px;
|
||
|
|
font-size: 1em;
|
||
|
|
}
|
||
|
|
.msger-input {
|
||
|
|
flex: 1;
|
||
|
|
background: #ddd;
|
||
|
|
}
|
||
|
|
.msger-send-btn {
|
||
|
|
margin-left: 10px;
|
||
|
|
background: rgb(0, 196, 65);
|
||
|
|
color: #fff;
|
||
|
|
font-weight: bold;
|
||
|
|
cursor: pointer;
|
||
|
|
transition: background 0.23s;
|
||
|
|
}
|
||
|
|
.msger-send-btn:hover {
|
||
|
|
background: rgb(0, 180, 50);
|
||
|
|
}
|
||
|
|
|
||
|
|
.msger-chat {
|
||
|
|
background-color: #fcfcfe;
|
||
|
|
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='260' height='260' viewBox='0 0 260 260'%3E%3Cg fill-rule='evenodd'%3E%3Cg fill='%23dddddd' fill-opacity='0.4'%3E%3Cpath d='M24.37 16c.2.65.39 1.32.54 2H21.17l1.17 2.34.45.9-.24.11V28a5 5 0 0 1-2.23 8.94l-.02.06a8 8 0 0 1-7.75 6h-20a8 8 0 0 1-7.74-6l-.02-.06A5 5 0 0 1-17.45 28v-6.76l-.79-1.58-.44-.9.9-.44.63-.32H-20a23.01 23.01 0 0 1 44.37-2zm-36.82 2a1 1 0 0 0-.44.1l-3.1 1.56.89 1.79 1.31-.66a3 3 0 0 1 2.69 0l2.2 1.1a1 1 0 0 0 .9 0l2.21-1.1a3 3 0 0 1 2.69 0l2.2 1.1a1 1 0 0 0 .9 0l2.21-1.1a3 3 0 0 1 2.69 0l2.2 1.1a1 1 0 0 0 .86.02l2.88-1.27a3 3 0 0 1 2.43 0l2.88 1.27a1 1 0 0 0 .85-.02l3.1-1.55-.89-1.79-1.42.71a3 3 0 0 1-2.56.06l-2.77-1.23a1 1 0 0 0-.4-.09h-.01a1 1 0 0 0-.4.09l-2.78 1.23a3 3 0 0 1-2.56-.06l-2.3-1.15a1 1 0 0 0-.45-.11h-.01a1 1 0 0 0-.44.1L.9 19.22a3 3 0 0 1-2.69 0l-2.2-1.1a1 1 0 0 0-.45-.11h-.01a1 1 0 0 0-.44.1l-2.21 1.11a3 3 0 0 1-2.69 0l-2.2-1.1a1 1 0 0 0-.45-.11h-.01zm0-2h-4.9a21.01 21.01 0 0 1 39.61 0h-2.09l-.06-.13-.26.13h-32.31zm30.35 7.68l1.36-.68h1.3v2h-36v-1.15l.34-.17 1.36-.68h2.59l1.36.68a3 3 0 0 0 2.69 0l1.36-.68h2.59l1.36.68a3 3 0 0 0 2.69 0L2.26 23h2.59l1.36.68a3 3 0 0 0 2.56.06l1.67-.74h3.23l1.67.74a3 3 0 0 0 2.56-.06zM-13.82 27l16.37 4.91L18.93 27h-32.75zm-.63 2h.34l16.66 5 16.67-5h.33a3 3 0 1 1 0 6h-34a3 3 0 1 1 0-6zm1.35 8a6 6 0 0 0 5.65 4h20a6 6 0 0 0 5.66-4H-13.1z'/%3E%3Cpath id='path6_fill-copy' d='M284.37 16c.2.65.39 1.32.54 2H281.17l1.17 2.34.45.9-.24.11V28a5 5 0 0 1-2.23 8.94l-.02.06a8 8 0 0 1-7.75 6h-20a8 8 0 0 1-7.74-6l-.02-.06a5 5 0 0 1-2.24-8.94v-6.76l-.79-1.58-.44-.9.9-.44.63-.32H240a23.01 23.01 0 0 1 44.37-2zm-36.82 2a1 1 0 0 0-.44.1l-3.1 1.56.89 1.79 1.31-.66a3 3 0 0 1 2.69 0l2.2 1.1a1 1 0 0 0 .9 0l2.21-1.1a3 3 0 0 1 2.69 0l2.2 1.1a1 1 0 0 0 .9 0l2.21-1.1a3 3 0 0 1 2.69 0l2.2 1.1a1 1 0 0 0 .86.02l2.88-1.27a3 3 0 0 1 2.43 0l2.88 1.27a1 1 0 0 0 .85-.02l3.1-1.55-.89-1.79-1.42.71a3 3 0 0 1-2.56.06l-2.77-1.23a1 1 0 0 0-.4-.09h-.01a1 1 0 0 0-.4.09l-2.78 1.23a3 3 0 0 1-2.56-.06l-2.3-1.15a1 1 0 0 0-.45-.11h-.01a1 1 0 0 0-.44.1l-2.21 1.11a3 3 0 0 1-2.69 0l-2.2-1.1a1 1 0 0 0-.45-.11h-.01a1 1 0 0 0-.44.1l-2.21 1.11a3 3 0 0 1-2.69 0l-2.2-1.1a1 1 0 0 0-.45-.11h-.01zm0-2h-4.9a21.01 21.01 0 0 1 39.61 0h-2.09l-.06-.13-.26.13h-32.31zm30.35 7.68l1.36-.68h1.3v2h-36v-1.15l.34-.17 1.36-.68h2.59l1.36.68a3 3 0 0 0 2.69 0l1.36-.68h2.59l1.36.68a3 3 0 0 0 2.69 0l1.36-.68h2.59l1.36.68a3 3 0 0 0 2.56.06l1.67-.74h3.23l1.67.74a3 3 0 0 0 2.56-.06zM246.18 27l16.37 4.91L278.93 27h-32.75zm-.63 2h.34l16.66 5 16.67-5h.33a3 3 0 1 1 0 6h-34a3 3 0 1 1 0-6zm1.35 8a6 6 0 0 0 5.65 4h20a6 6 0 0 0 5.66-4H246.9z'/%3E%3Cpath d='M159.5 21.02A9 9 0 0 0 151 15h-42a9 9 0 0 0-8.5 6.02 6 6 0 0 0 .02 11.96A8.99 8.99 0 0 0 109 45h42a9 9 0 0 0 8.48-12.02 6 6 0 0 0 .02-11.96zM151 17h-42a7 7 0 0 0-6.33 4h54.66a7 7 0 0 0-6.33-4zm-9.34 26a8.98 8.98 0 0 0 3.34-7h-2a7 7 0 0 1-7 7h-4.34a8.98 8.98 0 0 0 3.34-7h-2a7 7 0 0 1-7 7h-4.34a8.98 8.98 0 0 0 3.34-7h-2a7 7 0 0 1-7 7h-7a7 7 0 1 1 0-14h42a7 7 0 1 1 0 14h-9.34zM109 27a9 9 0 0 0-7.48 4H101a4 4 0 1 1 0-8h58a4 4 0 0 1 0 8h-.52a9 9 0 0 0-7.48-4h-42z'/%3E%3Cpath d='M39 115a8 8 0 1 0 0-16 8 8 0 0 0 0 16zm6-8a6 6 0 1 1-12 0 6 6 0 0 1 12 0zm-3-29v-2h8v-6H40a4 4 0 0 0-4 4v10H22l-1.33 4-.67 2h2.19L26 130h26l3.81-40H58l-.67-2L56 84H42v-6zm-4-4v10h2V74h8v-2h-8a2 2 0 0 0-2 2zm2 12h14.56l.67 2H22.77l.67-2H40zm13.8 4H24.2l3.62 38h22.36l3.62-38z'/%3E%3Cpath d='M129 92h-6v4h-6v4h-6v14h-3l.24 2 3.76 32h36l3.76-32 .24-2h-3v-14h-6v-4h-6v-4h-8zm18 22v-12h-4v4h3v8h1zm-3 0v-6h-4v6h4zm-6 6v-16h-4v19.17c1.6-.7 2.97-1.8 4-3.17zm-6 3.8V100h-4v23.8a10.04 10.04 0 0 0 4 0zm-6-.63V104h-4v16a10.04 10.04 0 0 0 4 3.17zm-6-9.17v-6h-4v6h4zm-6 0v-8h3v-4h-4v12h1zm27-12v-4h-4v4h3v4h1v-4zm-6 0v-8h-4v4h3v4h1zm-6-4v-4h-4v8h1v-4h3zm-6 4v-4h-4v8h1v-4h3zm7 24a12 12 0 0 0 11.83-10h7.92l-3.53 30h-32.44l-3.53-30h7.92A12 12 0 0 0 130 126z'/%3E%3Cpath d='M212 86v2h-4v-2h4zm4 0h-2v2h2v-2zm-20 0v.1a5 5 0 0 0-.56 9.65l.06.25 1.12 4.48a2 2 0 0 0 1.94 1.52h.01l7.02 24.55a2 2 0 0 0 1.92 1.45h4.98a2 2 0 0 0 1.92-1.45l7.02-24.55a2 2 0 0 0 1.95-1.52
|
||
|
|
}
|
||
|
|
</style>
|
||
|
|
|
||
|
|
<section class="msger">
|
||
|
|
<header class="msger-header">
|
||
|
|
<div class="msger-header-title">
|
||
|
|
<i class="fas fa-comment-alt"></i> SimpleChat
|
||
|
|
</div>
|
||
|
|
<div class="msger-header-options">
|
||
|
|
<span><i class="fas fa-cog"></i></span>
|
||
|
|
</div>
|
||
|
|
</header>
|
||
|
|
|
||
|
|
<main class="msger-chat">
|
||
|
|
<div class="msg left-msg">
|
||
|
|
<div
|
||
|
|
class="msg-img"
|
||
|
|
style="
|
||
|
|
background-image: url(https://image.flaticon.com/icons/svg/327/327779.svg);
|
||
|
|
"
|
||
|
|
></div>
|
||
|
|
|
||
|
|
<div class="msg-bubble">
|
||
|
|
<div class="msg-info">
|
||
|
|
<div class="msg-info-name">BOT</div>
|
||
|
|
<div class="msg-info-time">12:45</div>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<div class="msg-text">
|
||
|
|
Hi, welcome to SimpleChat! Go ahead and send me a message. 😄
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<div class="msg right-msg">
|
||
|
|
<div
|
||
|
|
class="msg-img"
|
||
|
|
style="
|
||
|
|
background-image: url(https://image.flaticon.com/icons/svg/145/145867.svg);
|
||
|
|
"
|
||
|
|
></div>
|
||
|
|
|
||
|
|
<div class="msg-bubble">
|
||
|
|
<div class="msg-info">
|
||
|
|
<div class="msg-info-name">Sajad</div>
|
||
|
|
<div class="msg-info-time">12:46</div>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<div class="msg-text">You can change your name in JS section!</div>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</main>
|
||
|
|
|
||
|
|
<form class="msger-inputarea">
|
||
|
|
<input
|
||
|
|
type="text"
|
||
|
|
class="msger-input"
|
||
|
|
placeholder="Enter your message..."
|
||
|
|
/>
|
||
|
|
<button type="submit" class="msger-send-btn">Send</button>
|
||
|
|
</form>
|
||
|
|
</section>
|
||
|
|
|
||
|
|
<script type="text/javascript">
|
||
|
|
const msgerForm = get(".msger-inputarea");
|
||
|
|
const msgerInput = get(".msger-input");
|
||
|
|
const msgerChat = get(".msger-chat");
|
||
|
|
|
||
|
|
const BOT_MSGS = [
|
||
|
|
"Hi, how are you?",
|
||
|
|
"Ohh... I can't understand what you trying to say. Sorry!",
|
||
|
|
"I like to play games... But I don't know how to play!",
|
||
|
|
"Sorry if my answers are not relevant. :))",
|
||
|
|
"I feel sleepy! :(",
|
||
|
|
];
|
||
|
|
|
||
|
|
// Icons made by Freepik from www.flaticon.com
|
||
|
|
const BOT_IMG = "https://image.flaticon.com/icons/svg/327/327779.svg";
|
||
|
|
const PERSON_IMG = "https://image.flaticon.com/icons/svg/145/145867.svg";
|
||
|
|
const BOT_NAME = "BOT";
|
||
|
|
const PERSON_NAME = "Sajad";
|
||
|
|
|
||
|
|
msgerForm.addEventListener("submit", (event) => {
|
||
|
|
event.preventDefault();
|
||
|
|
|
||
|
|
const msgText = msgerInput.value;
|
||
|
|
if (!msgText) return;
|
||
|
|
|
||
|
|
appendMessage(PERSON_NAME, PERSON_IMG, "right", msgText);
|
||
|
|
msgerInput.value = "";
|
||
|
|
|
||
|
|
botResponse();
|
||
|
|
});
|
||
|
|
|
||
|
|
function appendMessage(name, img, side, text) {
|
||
|
|
// Simple solution for small apps
|
||
|
|
const msgHTML = `
|
||
|
|
<div class="msg ${side}-msg">
|
||
|
|
<div class="msg-img" style="background-image: url(${img})"></div>
|
||
|
|
|
||
|
|
<div class="msg-bubble">
|
||
|
|
<div class="msg-info">
|
||
|
|
<div class="msg-info-name">${name}</div>
|
||
|
|
<div class="msg-info-time">${formatDate(new Date())}</div>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<div class="msg-text">${text}</div>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
`;
|
||
|
|
|
||
|
|
msgerChat.insertAdjacentHTML("beforeend", msgHTML);
|
||
|
|
msgerChat.scrollTop += 500;
|
||
|
|
}
|
||
|
|
|
||
|
|
function botResponse() {
|
||
|
|
const r = random(0, BOT_MSGS.length - 1);
|
||
|
|
const msgText = BOT_MSGS[r];
|
||
|
|
const delay = msgText.split(" ").length * 100;
|
||
|
|
|
||
|
|
setTimeout(() => {
|
||
|
|
appendMessage(BOT_NAME, BOT_IMG, "left", msgText);
|
||
|
|
}, delay);
|
||
|
|
}
|
||
|
|
|
||
|
|
// Utils
|
||
|
|
function get(selector, root = document) {
|
||
|
|
return root.querySelector(selector);
|
||
|
|
}
|
||
|
|
|
||
|
|
function formatDate(date) {
|
||
|
|
const h = "0" + date.getHours();
|
||
|
|
const m = "0" + date.getMinutes();
|
||
|
|
|
||
|
|
return `${h.slice(-2)}:${m.slice(-2)}`;
|
||
|
|
}
|
||
|
|
|
||
|
|
function random(min, max) {
|
||
|
|
return Math.floor(Math.random() * (max - min) + min);
|
||
|
|
}
|
||
|
|
</script>
|