├── .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 |
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 |
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 |
--------------------------------------------------------------------------------