MySafeCode commited on
Commit
d9bfdee
·
verified ·
1 Parent(s): cbfb0e7

Upload 2 files

Browse files
Files changed (2) hide show
  1. templates/chat.html +446 -0
  2. templates/login.html +161 -0
templates/chat.html ADDED
@@ -0,0 +1,446 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Whacky Chat - {{ session.username }}</title>
7
+ <script src="https://cdn.socket.io/4.7.2/socket.io.min.js"></script>
8
+ <style>
9
+ @import url('https://fonts.googleapis.com/css2?family=Rajdhani:wght@300;700&family=Orbitron:wght@700&display=swap');
10
+
11
+ * {
12
+ margin: 0;
13
+ padding: 0;
14
+ box-sizing: border-box;
15
+ }
16
+
17
+ body {
18
+ font-family: 'Rajdhani', sans-serif;
19
+ background: linear-gradient(45deg, #0f0f23, #1a1a3a, #2d1b69);
20
+ background-size: 400% 400%;
21
+ animation: gradientShift 8s ease infinite;
22
+ color: #fff;
23
+ height: 100vh;
24
+ overflow: hidden;
25
+ }
26
+
27
+ @keyframes gradientShift {
28
+ 0%{background-position:0% 50%}
29
+ 50%{background-position:100% 50%}
30
+ 100%{background-position:0% 50%}
31
+ }
32
+
33
+ .chat-container {
34
+ max-width: 800px;
35
+ margin: 0 auto;
36
+ height: 100vh;
37
+ display: flex;
38
+ flex-direction: column;
39
+ padding: 20px;
40
+ background: rgba(0,0,0,0.3);
41
+ backdrop-filter: blur(10px);
42
+ border: 2px solid rgba(255,255,255,0.1);
43
+ }
44
+
45
+ .header {
46
+ text-align: center;
47
+ padding: 20px;
48
+ border-bottom: 2px solid rgba(255,255,255,0.2);
49
+ margin-bottom: 20px;
50
+ position: relative;
51
+ }
52
+
53
+ .title {
54
+ font-family: 'Orbitron', monospace;
55
+ font-size: 2.5rem;
56
+ background: linear-gradient(45deg, #ff6ec4, #7873f5, #00ff88);
57
+ -webkit-background-clip: text;
58
+ -webkit-text-fill-color: transparent;
59
+ background-clip: text;
60
+ text-shadow: 0 0 20px rgba(255,110,196,0.5);
61
+ animation: titleGlow 2s ease-in-out infinite alternate;
62
+ }
63
+
64
+ @keyframes titleGlow {
65
+ from { filter: drop-shadow(0 0 10px rgba(255,110,196,0.5)); }
66
+ to { filter: drop-shadow(0 0 20px rgba(120,115,245,0.8)); }
67
+ }
68
+
69
+ .user-info {
70
+ text-align: center;
71
+ margin: 10px 0;
72
+ padding: 10px;
73
+ background: rgba(255,255,255,0.1);
74
+ border-radius: 10px;
75
+ border: 1px solid rgba(255,255,255,0.2);
76
+ }
77
+
78
+ .user-number {
79
+ font-size: 1.5rem;
80
+ color: #00ff88;
81
+ text-shadow: 0 0 10px #00ff88;
82
+ animation: userNumberPulse 1.5s ease-in-out infinite;
83
+ }
84
+
85
+ @keyframes userNumberPulse {
86
+ 0%, 100% { transform: scale(1); }
87
+ 50% { transform: scale(1.05); }
88
+ }
89
+
90
+ .logout-button {
91
+ position: absolute;
92
+ top: 10px;
93
+ right: 10px;
94
+ padding: 8px 15px;
95
+ background: rgba(255,0,0,0.3);
96
+ border: 1px solid rgba(255,0,0,0.5);
97
+ border-radius: 5px;
98
+ color: #fff;
99
+ text-decoration: none;
100
+ font-size: 0.9rem;
101
+ transition: all 0.3s ease;
102
+ }
103
+
104
+ .logout-button:hover {
105
+ background: rgba(255,0,0,0.5);
106
+ box-shadow: 0 0 10px rgba(255,0,0,0.3);
107
+ }
108
+
109
+ .messages-container {
110
+ flex: 1;
111
+ overflow-y: auto;
112
+ padding: 20px;
113
+ background: rgba(0,0,0,0.2);
114
+ border-radius: 15px;
115
+ margin-bottom: 20px;
116
+ border: 1px solid rgba(255,255,255,0.1);
117
+ }
118
+
119
+ .message {
120
+ margin: 15px 0;
121
+ padding: 15px;
122
+ border-radius: 15px;
123
+ background: rgba(255,255,255,0.1);
124
+ border: 1px solid rgba(255,255,255,0.2);
125
+ position: relative;
126
+ animation: messageSlide 0.5s ease-out;
127
+ }
128
+
129
+ @keyframes messageSlide {
130
+ from { transform: translateX(-100%); opacity: 0; }
131
+ to { transform: translateX(0); opacity: 1; }
132
+ }
133
+
134
+ .message.own {
135
+ background: linear-gradient(45deg, rgba(255,110,196,0.3), rgba(120,115,245,0.3));
136
+ border: 1px solid rgba(255,110,196,0.5);
137
+ text-align: right;
138
+ }
139
+
140
+ .message-header {
141
+ display: flex;
142
+ justify-content: space-between;
143
+ align-items: center;
144
+ margin-bottom: 8px;
145
+ }
146
+
147
+ .message-user {
148
+ font-weight: bold;
149
+ color: #00ff88;
150
+ text-shadow: 0 0 5px #00ff88;
151
+ }
152
+
153
+ .message-time {
154
+ font-size: 0.8rem;
155
+ color: rgba(255,255,255,0.6);
156
+ }
157
+
158
+ .message-content {
159
+ font-size: 1.1rem;
160
+ line-height: 1.4;
161
+ word-wrap: break-word;
162
+ }
163
+
164
+ .system-message {
165
+ text-align: center;
166
+ color: #ff6ec4;
167
+ font-style: italic;
168
+ margin: 10px 0;
169
+ animation: systemMessagePulse 2s ease-in-out infinite;
170
+ }
171
+
172
+ @keyframes systemMessagePulse {
173
+ 0%, 100% { opacity: 0.7; }
174
+ 50% { opacity: 1; }
175
+ }
176
+
177
+ .typing-indicator {
178
+ color: rgba(255,255,255,0.6);
179
+ font-style: italic;
180
+ padding: 10px;
181
+ margin-bottom: 10px;
182
+ animation: typingBlink 1s ease-in-out infinite;
183
+ }
184
+
185
+ @keyframes typingBlink {
186
+ 0%, 100% { opacity: 0.5; }
187
+ 50% { opacity: 1; }
188
+ }
189
+
190
+ .input-container {
191
+ display: flex;
192
+ gap: 10px;
193
+ padding: 20px;
194
+ background: rgba(255,255,255,0.1);
195
+ border-radius: 15px;
196
+ border: 1px solid rgba(255,255,255,0.2);
197
+ }
198
+
199
+ #messageInput {
200
+ flex: 1;
201
+ padding: 15px;
202
+ border: none;
203
+ border-radius: 10px;
204
+ background: rgba(0,0,0,0.3);
205
+ color: #fff;
206
+ font-size: 1rem;
207
+ border: 1px solid rgba(255,255,255,0.2);
208
+ transition: all 0.3s ease;
209
+ }
210
+
211
+ #messageInput:focus {
212
+ outline: none;
213
+ border-color: #00ff88;
214
+ box-shadow: 0 0 15px rgba(0,255,136,0.3);
215
+ }
216
+
217
+ #sendButton {
218
+ padding: 15px 25px;
219
+ border: none;
220
+ border-radius: 10px;
221
+ background: linear-gradient(45deg, #ff6ec4, #7873f5);
222
+ color: #fff;
223
+ font-weight: bold;
224
+ cursor: pointer;
225
+ transition: all 0.3s ease;
226
+ text-transform: uppercase;
227
+ letter-spacing: 1px;
228
+ }
229
+
230
+ #sendButton:hover {
231
+ transform: translateY(-2px);
232
+ box-shadow: 0 5px 15px rgba(255,110,196,0.4);
233
+ }
234
+
235
+ #sendButton:active {
236
+ transform: translateY(0);
237
+ }
238
+
239
+ .connected-users {
240
+ position: absolute;
241
+ top: 10px;
242
+ left: 10px;
243
+ background: rgba(0,255,136,0.2);
244
+ padding: 10px 15px;
245
+ border-radius: 20px;
246
+ border: 1px solid rgba(0,255,136,0.5);
247
+ font-size: 0.9rem;
248
+ }
249
+
250
+ .status-dot {
251
+ display: inline-block;
252
+ width: 8px;
253
+ height: 8px;
254
+ background: #00ff88;
255
+ border-radius: 50%;
256
+ margin-right: 5px;
257
+ animation: statusGlow 2s ease-in-out infinite;
258
+ }
259
+
260
+ @keyframes statusGlow {
261
+ 0%, 100% { box-shadow: 0 0 5px #00ff88; }
262
+ 50% { box-shadow: 0 0 15px #00ff88, 0 0 25px #00ff88; }
263
+ }
264
+
265
+ /* Scrollbar styling */
266
+ .messages-container::-webkit-scrollbar {
267
+ width: 8px;
268
+ }
269
+
270
+ .messages-container::-webkit-scrollbar-track {
271
+ background: rgba(0,0,0,0.1);
272
+ border-radius: 4px;
273
+ }
274
+
275
+ .messages-container::-webkit-scrollbar-thumb {
276
+ background: linear-gradient(45deg, #ff6ec4, #7873f5);
277
+ border-radius: 4px;
278
+ }
279
+ </style>
280
+ </head>
281
+ <body>
282
+ <div class="chat-container">
283
+ <div class="header">
284
+ <a href="/logout" class="logout-button">Logout</a>
285
+ <div class="title">WHACKY CHAT</div>
286
+ <div class="user-info">
287
+ <span id="userNumberDisplay" class="user-number">Connecting...</span>
288
+ </div>
289
+ </div>
290
+
291
+ <div class="connected-users">
292
+ <span class="status-dot"></span>
293
+ <span id="connectedCount">0 users online</span>
294
+ </div>
295
+
296
+ <div class="messages-container" id="messagesContainer">
297
+ <div id="typingIndicator" class="typing-indicator" style="display: none;">
298
+ Someone is typing...
299
+ </div>
300
+ </div>
301
+
302
+ <div class="input-container">
303
+ <input type="text" id="messageInput" placeholder="Type your whacky message here..." maxlength="500">
304
+ <button id="sendButton">SEND</button>
305
+ </div>
306
+ </div>
307
+
308
+ <script>
309
+ const socket = io();
310
+ let currentUserNumber = null;
311
+ let currentUsername = null;
312
+ let typingTimer;
313
+
314
+ // DOM elements
315
+ const messagesContainer = document.getElementById('messagesContainer');
316
+ const messageInput = document.getElementById('messageInput');
317
+ const sendButton = document.getElementById('sendButton');
318
+ const userNumberDisplay = document.getElementById('userNumberDisplay');
319
+ const connectedCount = document.getElementById('connectedCount');
320
+ const typingIndicator = document.getElementById('typingIndicator');
321
+
322
+ // Socket event handlers
323
+ socket.on('user_assigned', (data) => {
324
+ currentUserNumber = data.user_number;
325
+ currentUsername = data.username;
326
+ userNumberDisplay.textContent = `${currentUsername} (#${currentUserNumber})`;
327
+ addSystemMessage(data.message);
328
+ });
329
+
330
+ socket.on('user_joined', (data) => {
331
+ addSystemMessage(data.message);
332
+ updateConnectedCount(data.total_users);
333
+ });
334
+
335
+ socket.on('user_left', (data) => {
336
+ addSystemMessage(data.message);
337
+ updateConnectedCount(data.total_users);
338
+ });
339
+
340
+ socket.on('new_message', (data) => {
341
+ addMessage(data.user_number, data.username, data.message, data.timestamp);
342
+ });
343
+
344
+ socket.on('user_typing', (data) => {
345
+ showTypingIndicator(data.user_number, data.username);
346
+ });
347
+
348
+ // Message functions
349
+ function addMessage(userNumber, username, message, timestamp) {
350
+ const messageDiv = document.createElement('div');
351
+ messageDiv.className = 'message' + (userNumber === currentUserNumber ? ' own' : '');
352
+
353
+ const time = timestamp ? new Date(timestamp).toLocaleTimeString() : new Date().toLocaleTimeString();
354
+
355
+ messageDiv.innerHTML = `
356
+ <div class="message-header">
357
+ <span class="message-user">${username} (#${userNumber})</span>
358
+ <span class="message-time">${time}</span>
359
+ </div>
360
+ <div class="message-content">${escapeHtml(message)}</div>
361
+ `;
362
+
363
+ messagesContainer.insertBefore(messageDiv, typingIndicator);
364
+ scrollToBottom();
365
+ }
366
+
367
+ function addSystemMessage(message) {
368
+ const systemDiv = document.createElement('div');
369
+ systemDiv.className = 'system-message';
370
+ systemDiv.textContent = message;
371
+ messagesContainer.insertBefore(systemDiv, typingIndicator);
372
+ scrollToBottom();
373
+ }
374
+
375
+ function showTypingIndicator(userNumber, username) {
376
+ typingIndicator.textContent = `${username} is typing...`;
377
+ typingIndicator.style.display = 'block';
378
+
379
+ clearTimeout(typingTimer);
380
+ typingTimer = setTimeout(() => {
381
+ typingIndicator.style.display = 'none';
382
+ }, 2000);
383
+ }
384
+
385
+ function updateConnectedCount(count) {
386
+ connectedCount.textContent = `${count} user${count !== 1 ? 's' : ''} online`;
387
+ }
388
+
389
+ function scrollToBottom() {
390
+ messagesContainer.scrollTop = messagesContainer.scrollHeight;
391
+ }
392
+
393
+ function escapeHtml(text) {
394
+ const div = document.createElement('div');
395
+ div.textContent = text;
396
+ return div.innerHTML;
397
+ }
398
+
399
+ // Send message
400
+ function sendMessage() {
401
+ const message = messageInput.value.trim();
402
+ if (message && currentUserNumber) {
403
+ socket.emit('send_message', {
404
+ message: message,
405
+ timestamp: new Date().toISOString()
406
+ });
407
+ messageInput.value = '';
408
+ typingIndicator.style.display = 'none';
409
+ }
410
+ }
411
+
412
+ // Event listeners
413
+ sendButton.addEventListener('click', sendMessage);
414
+
415
+ messageInput.addEventListener('keypress', (e) => {
416
+ if (e.key === 'Enter') {
417
+ sendMessage();
418
+ } else {
419
+ // Emit typing event
420
+ socket.emit('typing', {});
421
+ }
422
+ });
423
+
424
+ // Initial focus
425
+ messageInput.focus();
426
+ </script>
427
+ </body>
428
+ </html>
429
+ ```
430
+
431
+ ## 🚀 **How to set up:**
432
+
433
+ 1. **Create a new folder** for your project
434
+ 2. **Save each file** with the exact names I provided above
435
+ 3. **Create a `templates` subfolder** and put the HTML files there
436
+ 4. **Run the setup:**
437
+ ```bash
438
+ pip install -r requirements.txt
439
+ python app.py
440
+ ```
441
+
442
+ 5. **Open your browser** to `http://localhost:5000`
443
+
444
+ The whacky chat app should now work perfectly with the login system and two-digit user numbers! 🎉
445
+
446
+ **Note:** I can't create actual download links, but you can easily copy-paste each file. If you need help creating a ZIP file manually, let me know!
templates/login.html ADDED
@@ -0,0 +1,161 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Whacky Chat - Login</title>
7
+ <style>
8
+ @import url('https://fonts.googleapis.com/css2?family=Rajdhani:wght@300;700&family=Orbitron:wght@700&display=swap');
9
+
10
+ * {
11
+ margin: 0;
12
+ padding: 0;
13
+ box-sizing: border-box;
14
+ }
15
+
16
+ body {
17
+ font-family: 'Rajdhani', sans-serif;
18
+ background: linear-gradient(45deg, #0f0f23, #1a1a3a, #2d1b69);
19
+ background-size: 400% 400%;
20
+ animation: gradientShift 8s ease infinite;
21
+ color: #fff;
22
+ height: 100vh;
23
+ display: flex;
24
+ justify-content: center;
25
+ align-items: center;
26
+ }
27
+
28
+ @keyframes gradientShift {
29
+ 0%{background-position:0% 50%}
30
+ 50%{background-position:100% 50%}
31
+ 100%{background-position:0% 50%}
32
+ }
33
+
34
+ .login-container {
35
+ background: rgba(0,0,0,0.3);
36
+ backdrop-filter: blur(10px);
37
+ border: 2px solid rgba(255,255,255,0.1);
38
+ border-radius: 20px;
39
+ padding: 40px;
40
+ text-align: center;
41
+ max-width: 400px;
42
+ width: 90%;
43
+ box-shadow: 0 10px 30px rgba(0,0,0,0.5);
44
+ }
45
+
46
+ .title {
47
+ font-family: 'Orbitron', monospace;
48
+ font-size: 2.5rem;
49
+ background: linear-gradient(45deg, #ff6ec4, #7873f5, #00ff88);
50
+ -webkit-background-clip: text;
51
+ -webkit-text-fill-color: transparent;
52
+ background-clip: text;
53
+ text-shadow: 0 0 20px rgba(255,110,196,0.5);
54
+ margin-bottom: 30px;
55
+ animation: titleGlow 2s ease-in-out infinite alternate;
56
+ }
57
+
58
+ @keyframes titleGlow {
59
+ from { filter: drop-shadow(0 0 10px rgba(255,110,196,0.5)); }
60
+ to { filter: drop-shadow(0 0 20px rgba(120,115,245,0.8)); }
61
+ }
62
+
63
+ .subtitle {
64
+ font-size: 1.2rem;
65
+ color: rgba(255,255,255,0.8);
66
+ margin-bottom: 30px;
67
+ }
68
+
69
+ .form-group {
70
+ margin-bottom: 25px;
71
+ }
72
+
73
+ .form-input {
74
+ width: 100%;
75
+ padding: 15px;
76
+ border: 2px solid rgba(255,255,255,0.2);
77
+ border-radius: 10px;
78
+ background: rgba(0,0,0,0.3);
79
+ color: #fff;
80
+ font-size: 1.1rem;
81
+ transition: all 0.3s ease;
82
+ }
83
+
84
+ .form-input:focus {
85
+ outline: none;
86
+ border-color: #00ff88;
87
+ box-shadow: 0 0 15px rgba(0,255,136,0.3);
88
+ }
89
+
90
+ .form-input::placeholder {
91
+ color: rgba(255,255,255,0.5);
92
+ }
93
+
94
+ .login-button {
95
+ width: 100%;
96
+ padding: 15px;
97
+ border: none;
98
+ border-radius: 10px;
99
+ background: linear-gradient(45deg, #ff6ec4, #7873f5);
100
+ color: #fff;
101
+ font-size: 1.1rem;
102
+ font-weight: bold;
103
+ cursor: pointer;
104
+ transition: all 0.3s ease;
105
+ text-transform: uppercase;
106
+ letter-spacing: 1px;
107
+ }
108
+
109
+ .login-button:hover {
110
+ transform: translateY(-2px);
111
+ box-shadow: 0 5px 15px rgba(255,110,196,0.4);
112
+ }
113
+
114
+ .login-button:active {
115
+ transform: translateY(0);
116
+ }
117
+
118
+ .info-text {
119
+ margin-top: 20px;
120
+ color: rgba(255,255,255,0.6);
121
+ font-size: 0.9rem;
122
+ }
123
+
124
+ .user-number-info {
125
+ background: rgba(0,255,136,0.2);
126
+ padding: 15px;
127
+ border-radius: 10px;
128
+ border: 1px solid rgba(0,255,136,0.5);
129
+ margin: 20px 0;
130
+ font-size: 0.9rem;
131
+ }
132
+ </style>
133
+ </head>
134
+ <body>
135
+ <div class="login-container">
136
+ <div class="title">WHACKY CHAT</div>
137
+ <div class="subtitle">Enter the Whacky Zone</div>
138
+
139
+ <form method="POST" action="/login">
140
+ <div class="form-group">
141
+ <input type="text"
142
+ name="username"
143
+ class="form-input"
144
+ placeholder="Enter your username"
145
+ required
146
+ maxlength="20">
147
+ </div>
148
+
149
+ <button type="submit" class="login-button">JOIN CHAT</button>
150
+ </form>
151
+
152
+ <div class="user-number-info">
153
+ You'll be assigned a unique two-digit user number (01, 02, 03...)
154
+ </div>
155
+
156
+ <div class="info-text">
157
+ No password needed - just pick a username and join the fun!
158
+ </div>
159
+ </div>
160
+ </body>
161
+ </html>