├── .github └── FUNDING.yml ├── .gitignore ├── app.js ├── index.html └── style.css /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | patreon: ebenezerdon 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .history -------------------------------------------------------------------------------- /app.js: -------------------------------------------------------------------------------- 1 | // @ts-nocheck 2 | 3 | const johnSelectorBtn = document.querySelector('#john-selector') 4 | const janeSelectorBtn = document.querySelector('#jane-selector') 5 | const chatHeader = document.querySelector('.chat-header') 6 | const chatMessages = document.querySelector('.chat-messages') 7 | const chatInputForm = document.querySelector('.chat-input-form') 8 | const chatInput = document.querySelector('.chat-input') 9 | const clearChatBtn = document.querySelector('.clear-chat-button') 10 | 11 | const messages = JSON.parse(localStorage.getItem('messages')) || [] 12 | 13 | const createChatMessageElement = (message) => ` 14 |
15 |
${message.sender}
16 |
${message.text}
17 |
${message.timestamp}
18 |
19 | ` 20 | 21 | window.onload = () => { 22 | messages.forEach((message) => { 23 | chatMessages.innerHTML += createChatMessageElement(message) 24 | }) 25 | } 26 | 27 | let messageSender = 'John' 28 | 29 | const updateMessageSender = (name) => { 30 | messageSender = name 31 | chatHeader.innerText = `${messageSender} chatting...` 32 | chatInput.placeholder = `Type here, ${messageSender}...` 33 | 34 | if (name === 'John') { 35 | johnSelectorBtn.classList.add('active-person') 36 | janeSelectorBtn.classList.remove('active-person') 37 | } 38 | if (name === 'Jane') { 39 | janeSelectorBtn.classList.add('active-person') 40 | johnSelectorBtn.classList.remove('active-person') 41 | } 42 | 43 | /* auto-focus the input field */ 44 | chatInput.focus() 45 | } 46 | 47 | johnSelectorBtn.onclick = () => updateMessageSender('John') 48 | janeSelectorBtn.onclick = () => updateMessageSender('Jane') 49 | 50 | const sendMessage = (e) => { 51 | e.preventDefault() 52 | 53 | const timestamp = new Date().toLocaleString('en-US', { hour: 'numeric', minute: 'numeric', hour12: true }) 54 | const message = { 55 | sender: messageSender, 56 | text: chatInput.value, 57 | timestamp, 58 | } 59 | 60 | /* Save message to local storage */ 61 | messages.push(message) 62 | localStorage.setItem('messages', JSON.stringify(messages)) 63 | 64 | /* Add message to DOM */ 65 | chatMessages.innerHTML += createChatMessageElement(message) 66 | 67 | /* Clear input field */ 68 | chatInputForm.reset() 69 | 70 | /* Scroll to bottom of chat messages */ 71 | chatMessages.scrollTop = chatMessages.scrollHeight 72 | } 73 | 74 | chatInputForm.addEventListener('submit', sendMessage) 75 | 76 | clearChatBtn.addEventListener('click', () => { 77 | localStorage.clear() 78 | chatMessages.innerHTML = '' 79 | }) 80 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Chat App 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 |
15 |
16 |

John chatting...

17 | 18 |
19 |
20 |
John
21 |
Hey Jane, what's up?
22 |
10:30 AM
23 |
24 |
25 |
Jane
26 |
Not much, just living the dream. How about you?
27 |
10:35 AM
28 |
29 |
30 | 31 |
32 | 33 | 34 |
35 | 36 |
37 | 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /style.css: -------------------------------------------------------------------------------- 1 | body { 2 | background-image: linear-gradient( 3 | 23deg, 4 | hsl(49deg 100% 69%) 0%, 5 | hsl(16deg 80% 61%) 2%, 6 | hsl(330deg 81% 34%) 12%, 7 | hsl(259deg 100% 15%) 50%, 8 | hsl(212deg 100% 25%) 88%, 9 | hsl(197deg 100% 30%) 98%, 10 | hsl(183deg 79% 36%) 100% 11 | ); 12 | height: 100vh; 13 | } 14 | 15 | .button { 16 | border: none; 17 | padding: 0.625em; 18 | border-radius: 0.5em; 19 | cursor: pointer; 20 | } 21 | 22 | .button:hover { 23 | filter: brightness(0.9); 24 | } 25 | 26 | .button:active { 27 | transform: translateY(2px); 28 | } 29 | 30 | .person-selector { 31 | display: flex; 32 | justify-content: center; 33 | gap: 1em; 34 | margin: 3em auto 1em; 35 | max-width: 40em; 36 | } 37 | 38 | .person-selector-button { 39 | width: 100%; 40 | background-color: #15202b; 41 | color: #fff; 42 | font-size: 1.1em; 43 | } 44 | 45 | .active-person { 46 | background: #08529d; 47 | box-shadow: 0 0 0.5em 0.1em #c3c3c333; 48 | } 49 | 50 | .chat-container { 51 | background: #15202b; 52 | font-family: 'Roboto', sans-serif; 53 | border-radius: 0.5em; 54 | padding: 0.5em 1.25em; 55 | margin: auto; 56 | max-width: 37.5em; 57 | height: 37.5em; 58 | box-shadow: 0 0 1.25em 0.5em #c3c3c333; 59 | } 60 | 61 | .chat-header { 62 | margin-bottom: 1em; 63 | color: #fff; 64 | } 65 | 66 | .chat-header h2 { 67 | font-size: 1.25em; 68 | font-weight: bold; 69 | } 70 | 71 | .chat-messages { 72 | height: 23em; 73 | overflow-y: scroll; 74 | } 75 | 76 | .chat-messages::-webkit-scrollbar { 77 | display: none; 78 | } 79 | 80 | .message { 81 | padding: 0.625em; 82 | border-radius: 1em; 83 | margin-bottom: 0.625em; 84 | display: flex; 85 | flex-direction: column; 86 | color: #fff; 87 | } 88 | 89 | .message-sender { 90 | font-weight: bold; 91 | margin-bottom: 0.31em; 92 | } 93 | 94 | .message-text { 95 | font-size: 1em; 96 | margin-bottom: 0.31em; 97 | word-wrap: break-word; 98 | } 99 | 100 | .message-timestamp { 101 | font-size: 0.75em; 102 | text-align: right; 103 | } 104 | 105 | .blue-bg { 106 | background-color: #1c9bef; 107 | } 108 | 109 | .gray-bg { 110 | background-color: #3d5365; 111 | } 112 | 113 | .chat-input-form { 114 | display: flex; 115 | align-items: center; 116 | margin-top: 2em; 117 | gap: 0.625em; 118 | } 119 | 120 | .chat-input { 121 | padding: 0.625em; 122 | border: none; 123 | border-radius: 0.5em; 124 | background-color: #f5f5f5; 125 | color: #333; 126 | font-size: 1em; 127 | flex-grow: 1; 128 | } 129 | 130 | .send-button { 131 | background-color: #1c9bef; 132 | color: #fff; 133 | font-size: 1em; 134 | font-weight: bold; 135 | } 136 | 137 | .clear-chat-button { 138 | display: block; 139 | margin: 2.5em auto; 140 | } 141 | --------------------------------------------------------------------------------