samirerty commited on
Commit
9c062a7
·
verified ·
1 Parent(s): e6c0588

Upload folder using huggingface_hub

Browse files
Files changed (1) hide show
  1. index.html +1017 -19
index.html CHANGED
@@ -1,19 +1,1017 @@
1
- <!doctype html>
2
- <html>
3
- <head>
4
- <meta charset="utf-8" />
5
- <meta name="viewport" content="width=device-width" />
6
- <title>My static Space</title>
7
- <link rel="stylesheet" href="style.css" />
8
- </head>
9
- <body>
10
- <div class="card">
11
- <h1>Welcome to your static Space!</h1>
12
- <p>You can modify this app directly by editing <i>index.html</i> in the Files and versions tab.</p>
13
- <p>
14
- Also don't forget to check the
15
- <a href="https://huggingface.co/docs/hub/spaces" target="_blank">Spaces documentation</a>.
16
- </p>
17
- </div>
18
- </body>
19
- </html>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="fa" dir="rtl">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
6
+ <title>چت روم مینیمال | Minimal Chat</title>
7
+
8
+ <!-- Importing Vazirmatn Font -->
9
+ <link href="https://cdn.jsdelivr.net/gh/rastikerdar/vazirmatn@v33.003/Vazirmatn-font-face.css" rel="stylesheet" type="text/css" />
10
+
11
+ <!-- Importing FontAwesome for Icons -->
12
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
13
+
14
+ <style>
15
+ :root {
16
+ --primary: #6366f1;
17
+ --primary-dark: #4f46e5;
18
+ --secondary: #ec4899;
19
+ --bg-gradient: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
20
+ --glass-bg: rgba(255, 255, 255, 0.1);
21
+ --glass-border: rgba(255, 255, 255, 0.2);
22
+ --glass-shadow: 0 8px 32px 0 rgba(31, 38, 135, 0.37);
23
+ --text-main: #ffffff;
24
+ --text-muted: #e2e8f0;
25
+ --danger: #ef4444;
26
+ --success: #10b981;
27
+ --msg-sent: rgba(99, 102, 241, 0.3);
28
+ --msg-received: rgba(255, 255, 255, 0.1);
29
+ }
30
+
31
+ * {
32
+ box-sizing: border-box;
33
+ margin: 0;
34
+ padding: 0;
35
+ -webkit-tap-highlight-color: transparent;
36
+ }
37
+
38
+ body {
39
+ font-family: 'Vazirmatn', sans-serif;
40
+ background: var(--bg-gradient);
41
+ color: var(--text-main);
42
+ height: 100vh;
43
+ overflow: hidden;
44
+ display: flex;
45
+ justify-content: center;
46
+ align-items: center;
47
+ }
48
+
49
+ /* --- Glass Container --- */
50
+ .app-container {
51
+ width: 100%;
52
+ height: 100%;
53
+ max-width: 480px; /* Mobile App feel */
54
+ background: var(--glass-bg);
55
+ backdrop-filter: blur(12px);
56
+ -webkit-backdrop-filter: blur(12px);
57
+ border: 1px solid var(--glass-border);
58
+ border-radius: 20px;
59
+ box-shadow: var(--glass-shadow);
60
+ position: relative;
61
+ overflow: hidden;
62
+ display: flex;
63
+ flex-direction: column;
64
+ }
65
+
66
+ @media (min-width: 481px) {
67
+ .app-container {
68
+ height: 90vh;
69
+ margin: 20px;
70
+ }
71
+ }
72
+
73
+ /* --- Header --- */
74
+ header {
75
+ padding: 15px 20px;
76
+ display: flex;
77
+ justify-content: space-between;
78
+ align-items: center;
79
+ background: rgba(0, 0, 0, 0.1);
80
+ border-bottom: 1px solid var(--glass-border);
81
+ z-index: 10;
82
+ }
83
+
84
+ .header-title {
85
+ font-size: 1.1rem;
86
+ font-weight: 700;
87
+ display: flex;
88
+ align-items: center;
89
+ gap: 10px;
90
+ }
91
+
92
+ .status-dot {
93
+ width: 10px;
94
+ height: 10px;
95
+ background: var(--success);
96
+ border-radius: 50%;
97
+ box-shadow: 0 0 10px var(--success);
98
+ }
99
+
100
+ .built-with {
101
+ font-size: 0.7rem;
102
+ color: rgba(255, 255, 255, 0.5);
103
+ text-decoration: none;
104
+ margin-top: 5px;
105
+ display: block;
106
+ text-align: center;
107
+ }
108
+
109
+ /* --- Screens Management --- */
110
+ .screen {
111
+ display: none;
112
+ flex: 1;
113
+ flex-direction: column;
114
+ height: 100%;
115
+ animation: fadeIn 0.4s ease;
116
+ }
117
+
118
+ .screen.active {
119
+ display: flex;
120
+ }
121
+
122
+ @keyframes fadeIn {
123
+ from { opacity: 0; transform: translateY(10px); }
124
+ to { opacity: 1; transform: translateY(0); }
125
+ }
126
+
127
+ /* --- Auth Screen --- */
128
+ .auth-screen {
129
+ justify-content: center;
130
+ align-items: center;
131
+ padding: 30px;
132
+ text-align: center;
133
+ }
134
+
135
+ .auth-icon {
136
+ font-size: 3rem;
137
+ margin-bottom: 20px;
138
+ color: var(--primary);
139
+ text-shadow: 0 0 20px rgba(99, 102, 241, 0.5);
140
+ }
141
+
142
+ .auth-input {
143
+ width: 100%;
144
+ padding: 15px;
145
+ margin: 10px 0;
146
+ background: rgba(255, 255, 255, 0.1);
147
+ border: 1px solid var(--glass-border);
148
+ border-radius: 12px;
149
+ color: white;
150
+ font-family: 'Vazirmatn', sans-serif;
151
+ font-size: 1rem;
152
+ text-align: center;
153
+ outline: none;
154
+ transition: 0.3s;
155
+ }
156
+
157
+ .auth-input:focus {
158
+ background: rgba(255, 255, 255, 0.2);
159
+ border-color: var(--primary);
160
+ }
161
+
162
+ .btn-primary {
163
+ width: 100%;
164
+ padding: 15px;
165
+ background: var(--primary);
166
+ border: none;
167
+ border-radius: 12px;
168
+ color: white;
169
+ font-family: 'Vazirmatn', sans-serif;
170
+ font-size: 1rem;
171
+ font-weight: bold;
172
+ cursor: pointer;
173
+ transition: 0.3s;
174
+ margin-top: 10px;
175
+ }
176
+
177
+ .btn-primary:active {
178
+ transform: scale(0.98);
179
+ background: var(--primary-dark);
180
+ }
181
+
182
+ /* --- Room List Screen --- */
183
+ .room-list {
184
+ padding: 20px;
185
+ overflow-y: auto;
186
+ flex: 1;
187
+ }
188
+
189
+ .room-card {
190
+ background: rgba(255, 255, 255, 0.1);
191
+ border: 1px solid var(--glass-border);
192
+ padding: 15px;
193
+ border-radius: 15px;
194
+ margin-bottom: 15px;
195
+ display: flex;
196
+ justify-content: space-between;
197
+ align-items: center;
198
+ cursor: pointer;
199
+ transition: 0.3s;
200
+ }
201
+
202
+ .room-card:hover {
203
+ background: rgba(255, 255, 255, 0.2);
204
+ transform: translateX(-5px);
205
+ }
206
+
207
+ .room-info h3 {
208
+ font-size: 1rem;
209
+ margin-bottom: 5px;
210
+ }
211
+
212
+ .room-info p {
213
+ font-size: 0.8rem;
214
+ color: var(--text-muted);
215
+ }
216
+
217
+ .add-room-btn {
218
+ width: 100%;
219
+ padding: 20px;
220
+ border: 2px dashed rgba(255, 255, 255, 0.3);
221
+ border-radius: 15px;
222
+ background: transparent;
223
+ color: white;
224
+ font-size: 1.2rem;
225
+ cursor: pointer;
226
+ transition: 0.3s;
227
+ }
228
+
229
+ .add-room-btn:hover {
230
+ border-color: var(--primary);
231
+ background: rgba(99, 102, 241, 0.1);
232
+ }
233
+
234
+ /* --- Chat Screen --- */
235
+ .chat-header {
236
+ padding: 10px 15px;
237
+ background: rgba(0, 0, 0, 0.2);
238
+ display: flex;
239
+ align-items: center;
240
+ gap: 10px;
241
+ border-bottom: 1px solid var(--glass-border);
242
+ }
243
+
244
+ .chat-back {
245
+ font-size: 1.2rem;
246
+ cursor: pointer;
247
+ padding: 5px;
248
+ }
249
+
250
+ .chat-messages {
251
+ flex: 1;
252
+ padding: 15px;
253
+ overflow-y: auto;
254
+ display: flex;
255
+ flex-direction: column;
256
+ gap: 10px;
257
+ scroll-behavior: smooth;
258
+ }
259
+
260
+ .message {
261
+ max-width: 80%;
262
+ padding: 10px 15px;
263
+ border-radius: 18px;
264
+ font-size: 0.95rem;
265
+ position: relative;
266
+ word-wrap: break-word;
267
+ animation: popIn 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275);
268
+ }
269
+
270
+ @keyframes popIn {
271
+ from { opacity: 0; transform: scale(0.8); }
272
+ to { opacity: 1; transform: scale(1); }
273
+ }
274
+
275
+ .message.sent {
276
+ align-self: flex-end;
277
+ background: var(--msg-sent);
278
+ border-bottom-left-radius: 4px;
279
+ border: 1px solid rgba(99, 102, 241, 0.3);
280
+ }
281
+
282
+ .message.received {
283
+ align-self: flex-start;
284
+ background: var(--msg-received);
285
+ border-bottom-right-radius: 4px;
286
+ border: 1px solid rgba(255, 255, 255, 0.1);
287
+ }
288
+
289
+ .message-meta {
290
+ display: flex;
291
+ justify-content: flex-end;
292
+ align-items: center;
293
+ gap: 5px;
294
+ margin-top: 5px;
295
+ font-size: 0.7rem;
296
+ color: rgba(255, 255, 255, 0.6);
297
+ }
298
+
299
+ .message-actions {
300
+ display: flex;
301
+ gap: 8px;
302
+ opacity: 0;
303
+ transition: 0.2s;
304
+ }
305
+
306
+ .message:hover .message-actions {
307
+ opacity: 1;
308
+ }
309
+
310
+ .action-btn {
311
+ background: none;
312
+ border: none;
313
+ color: rgba(255, 255, 255, 0.6);
314
+ cursor: pointer;
315
+ padding: 2px;
316
+ }
317
+
318
+ .action-btn:hover {
319
+ color: white;
320
+ }
321
+
322
+ /* --- Reply Preview --- */
323
+ .reply-preview {
324
+ background: rgba(0, 0, 0, 0.2);
325
+ padding: 8px 15px;
326
+ border-radius: 10px;
327
+ margin-bottom: 10px;
328
+ font-size: 0.8rem;
329
+ display: none;
330
+ align-items: center;
331
+ justify-content: space-between;
332
+ border-right: 3px solid var(--primary);
333
+ }
334
+
335
+ /* --- Chat Input Area --- */
336
+ .chat-input-area {
337
+ padding: 10px;
338
+ background: rgba(0, 0, 0, 0.2);
339
+ display: flex;
340
+ align-items: center;
341
+ gap: 10px;
342
+ }
343
+
344
+ .emoji-trigger {
345
+ font-size: 1.5rem;
346
+ cursor: pointer;
347
+ padding: 5px;
348
+ }
349
+
350
+ .chat-input {
351
+ flex: 1;
352
+ background: rgba(255, 255, 255, 0.1);
353
+ border: none;
354
+ padding: 12px 15px;
355
+ border-radius: 25px;
356
+ color: white;
357
+ font-family: 'Vazirmatn', sans-serif;
358
+ outline: none;
359
+ }
360
+
361
+ .send-btn {
362
+ background: var(--primary);
363
+ width: 45px;
364
+ height: 45px;
365
+ border-radius: 50%;
366
+ border: none;
367
+ color: white;
368
+ font-size: 1.2rem;
369
+ cursor: pointer;
370
+ display: flex;
371
+ justify-content: center;
372
+ align-items: center;
373
+ transition: 0.3s;
374
+ }
375
+
376
+ .send-btn:hover {
377
+ background: var(--primary-dark);
378
+ transform: scale(1.1);
379
+ }
380
+
381
+ /* --- Emoji Picker --- */
382
+ .emoji-picker {
383
+ position: absolute;
384
+ bottom: 80px;
385
+ left: 20px;
386
+ background: rgba(0, 0, 0, 0.8);
387
+ backdrop-filter: blur(10px);
388
+ padding: 15px;
389
+ border-radius: 15px;
390
+ display: grid;
391
+ grid-template-columns: repeat(6, 1fr);
392
+ gap: 10px;
393
+ z-index: 100;
394
+ display: none; /* Hidden by default */
395
+ border: 1px solid var(--glass-border);
396
+ }
397
+
398
+ .emoji-picker.active {
399
+ display: grid;
400
+ }
401
+
402
+ .emoji-btn {
403
+ font-size: 1.5rem;
404
+ cursor: pointer;
405
+ transition: 0.2s;
406
+ }
407
+
408
+ .emoji-btn:hover {
409
+ transform: scale(1.2);
410
+ }
411
+
412
+ /* --- Modals --- */
413
+ .modal-overlay {
414
+ position: absolute;
415
+ top: 0;
416
+ left: 0;
417
+ width: 100%;
418
+ height: 100%;
419
+ background: rgba(0, 0, 0, 0.6);
420
+ backdrop-filter: blur(5px);
421
+ display: flex;
422
+ justify-content: center;
423
+ align-items: center;
424
+ z-index: 200;
425
+ opacity: 0;
426
+ pointer-events: none;
427
+ transition: 0.3s;
428
+ }
429
+
430
+ .modal-overlay.active {
431
+ opacity: 1;
432
+ pointer-events: all;
433
+ }
434
+
435
+ .modal {
436
+ background: #1e1e2e;
437
+ width: 85%;
438
+ padding: 25px;
439
+ border-radius: 20px;
440
+ border: 1px solid var(--glass-border);
441
+ transform: scale(0.9);
442
+ transition: 0.3s;
443
+ }
444
+
445
+ .modal-overlay.active .modal {
446
+ transform: scale(1);
447
+ }
448
+
449
+ .modal h2 {
450
+ margin-bottom: 15px;
451
+ color: white;
452
+ }
453
+
454
+ .modal input {
455
+ width: 100%;
456
+ padding: 12px;
457
+ margin-bottom: 20px;
458
+ background: rgba(255, 255, 255, 0.05);
459
+ border: 1px solid rgba(255, 255, 255, 0.1);
460
+ border-radius: 10px;
461
+ color: white;
462
+ font-family: 'Vazirmatn', sans-serif;
463
+ }
464
+
465
+ .modal-actions {
466
+ display: flex;
467
+ gap: 10px;
468
+ }
469
+
470
+ .btn-cancel {
471
+ flex: 1;
472
+ padding: 12px;
473
+ background: rgba(255, 255, 255, 0.1);
474
+ border: none;
475
+ border-radius: 10px;
476
+ color: white;
477
+ cursor: pointer;
478
+ }
479
+
480
+ .btn-confirm {
481
+ flex: 1;
482
+ padding: 12px;
483
+ background: var(--primary);
484
+ border: none;
485
+ border-radius: 10px;
486
+ color: white;
487
+ cursor: pointer;
488
+ }
489
+
490
+ /* --- Toast Notification --- */
491
+ .toast {
492
+ position: absolute;
493
+ top: 20px;
494
+ left: 50%;
495
+ transform: translateX(-50%) translateY(-20px);
496
+ background: rgba(0, 0, 0, 0.8);
497
+ padding: 10px 20px;
498
+ border-radius: 20px;
499
+ font-size: 0.9rem;
500
+ opacity: 0;
501
+ transition: 0.3s;
502
+ pointer-events: none;
503
+ z-index: 300;
504
+ white-space: nowrap;
505
+ }
506
+
507
+ .toast.show {
508
+ opacity: 1;
509
+ transform: translateX(-50%) translateY(0);
510
+ }
511
+
512
+ /* --- Reactions --- */
513
+ .reaction-bubble {
514
+ position: absolute;
515
+ top: -20px;
516
+ left: 50%;
517
+ transform: translateX(-50%) scale(0);
518
+ font-size: 1.5rem;
519
+ transition: 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275);
520
+ pointer-events: none;
521
+ z-index: 50;
522
+ }
523
+
524
+ .reaction-bubble.show {
525
+ transform: translateX(-50%) scale(1);
526
+ }
527
+
528
+ </style>
529
+ </head>
530
+ <body>
531
+
532
+ <div class="app-container">
533
+ <header>
534
+ <div class="header-title">
535
+ <div class="status-dot"></div>
536
+ <span id="app-title">چت روم</span>
537
+ </div>
538
+ <a href="https://huggingface.co/spaces/akhaliq/anycoder" target="_blank" class="built-with">Built with anycoder</a>
539
+ </header>
540
+
541
+ <!-- Toast Notification -->
542
+ <div id="toast" class="toast">پیام سیستم</div>
543
+
544
+ <!-- Screen 1: Authentication -->
545
+ <div id="auth-screen" class="screen active auth-screen">
546
+ <i class="fas fa-comments auth-icon"></i>
547
+ <h2 style="margin-bottom: 20px;">خوش آمدید</h2>
548
+ <input type="tel" id="phone-input" class="auth-input" placeholder="شماره موبایل خود را وارد کنید" maxlength="11">
549
+ <button class="btn-primary" onclick="App.auth.login()">ورود / ثبت‌نام</button>
550
+ </div>
551
+
552
+ <!-- Screen 2: Room List -->
553
+ <div id="room-screen" class="screen">
554
+ <div class="room-list">
555
+ <div id="rooms-container">
556
+ <!-- Rooms injected here -->
557
+ </div>
558
+ <button class="add-room-btn" onclick="App.rooms.openCreateModal()">
559
+ <i class="fas fa-plus"></i> ایجاد اتاق جدید
560
+ </button>
561
+ </div>
562
+ </div>
563
+
564
+ <!-- Screen 3: Chat Room -->
565
+ <div id="chat-screen" class="screen">
566
+ <div class="chat-header">
567
+ <i class="fas fa-arrow-right chat-back" onclick="App.ui.navigate('room-screen')"></i>
568
+ <div style="flex:1">
569
+ <h3 id="chat-room-name" style="font-size: 1rem;">نام اتاق</h3>
570
+ <p id="chat-room-count" style="font-size: 0.7rem; color: var(--text-muted);">0 نفر آنلاین</p>
571
+ </div>
572
+ <i class="fas fa-share-alt" style="cursor: pointer;" onclick="App.chat.copyLink()" title="کپی لینک"></i>
573
+ </div>
574
+
575
+ <div class="chat-messages" id="chat-messages">
576
+ <!-- Messages injected here -->
577
+ </div>
578
+
579
+ <!-- Reply Preview -->
580
+ <div id="reply-preview" class="reply-preview">
581
+ <span id="reply-text">پاسخ به...</span>
582
+ <i class="fas fa-times" style="cursor: pointer;" onclick="App.chat.cancelReply()"></i>
583
+ </div>
584
+
585
+ <!-- Emoji Picker -->
586
+ <div class="emoji-picker" id="emoji-picker">
587
+ <div class="emoji-btn" onclick="App.chat.insertEmoji('😀')">😀</div>
588
+ <div class="emoji-btn" onclick="App.chat.insertEmoji('😂')">😂</div>
589
+ <div class="emoji-btn" onclick="App.chat.insertEmoji('😍')">😍</div>
590
+ <div class="emoji-btn" onclick="App.chat.insertEmoji('😎')">😎</div>
591
+ <div class="emoji-btn" onclick="App.chat.insertEmoji('🤔')">🤔</div>
592
+ <div class="emoji-btn" onclick="App.chat.insertEmoji('👍')">👍</div>
593
+ <div class="emoji-btn" onclick="App.chat.insertEmoji('👎')">👎</div>
594
+ <div class="emoji-btn" onclick="App.chat.insertEmoji('🎉')">🎉</div>
595
+ <div class="emoji-btn" onclick="App.chat.insertEmoji('❤️')">❤️</div>
596
+ <div class="emoji-btn" onclick="App.chat.insertEmoji('🔥')">🔥</div>
597
+ <div class="emoji-btn" onclick="App.chat.insertEmoji('✨')">✨</div>
598
+ <div class="emoji-btn" onclick="App.chat.insertEmoji('👋')">👋</div>
599
+ </div>
600
+
601
+ <div class="chat-input-area">
602
+ <i class="fas fa-smile emoji-trigger" onclick="App.ui.toggleEmojiPicker()"></i>
603
+ <input type="text" id="message-input" class="chat-input" placeholder="پیام خود را بنویسید..." onkeypress="App.chat.handleKeyPress(event)">
604
+ <button class="send-btn" onclick="App.chat.sendMessage()">
605
+ <i class="fas fa-paper-plane"></i>
606
+ </button>
607
+ </div>
608
+ </div>
609
+
610
+ <!-- Create Room Modal -->
611
+ <div id="create-room-modal" class="modal-overlay">
612
+ <div class="modal">
613
+ <h2>ساخت اتاق جدید</h2>
614
+ <input type="text" id="new-room-name" placeholder="نام اتاق را وارد کنید">
615
+ <div class="modal-actions">
616
+ <button class="btn-cancel" onclick="App.rooms.closeModal()">انصراف</button>
617
+ <button class="btn-confirm" onclick="App.rooms.createRoom()">ساخت</button>
618
+ </div>
619
+ </div>
620
+ </div>
621
+
622
+ <!-- Delete Confirmation Modal -->
623
+ <div id="delete-modal" class="modal-overlay">
624
+ <div class="modal">
625
+ <h2>حذف پیام</h2>
626
+ <p style="margin-bottom: 20px; color: #ccc;">آیا از حذف این پیام اطمینان دارید؟</p>
627
+ <div class="modal-actions">
628
+ <button class="btn-cancel" onclick="App.chat.closeDeleteModal()">انصراف</button>
629
+ <button class="btn-confirm" style="background: var(--danger);" onclick="App.chat.confirmDelete()">حذف</button>
630
+ </div>
631
+ </div>
632
+ </div>
633
+
634
+ </div>
635
+
636
+ <script>
637
+ /**
638
+ * Main Application Logic
639
+ * Implements modular structure within a single file
640
+ */
641
+ const App = {
642
+ state: {
643
+ user: null,
644
+ currentRoomId: null,
645
+ rooms: [],
646
+ messages: [],
647
+ replyingTo: null,
648
+ deletingMessageId: null
649
+ },
650
+
651
+ init: function() {
652
+ // Load data from localStorage or initialize defaults
653
+ const savedRooms = localStorage.getItem('chat_rooms');
654
+ const savedMessages = localStorage.getItem('chat_messages');
655
+
656
+ if (savedRooms) {
657
+ this.state.rooms = JSON.parse(savedRooms);
658
+ } else {
659
+ // Default rooms
660
+ this.state.rooms = [
661
+ { id: 1, name: 'گفتگوی عمومی', lastMsg: 'سلام همه دوستان!', time: '10:30' },
662
+ { id: 2, name: 'تکنولوژی', lastMsg: 'کدام گوشی را پیشنهاد می‌کنید؟', time: '09:15' }
663
+ ];
664
+ }
665
+
666
+ if (savedMessages) {
667
+ this.state.messages = JSON.parse(savedMessages);
668
+ }
669
+
670
+ // Initialize UI
671
+ this.ui.renderRooms();
672
+
673
+ // Setup Swipe Gestures
674
+ this.gestures.init();
675
+ },
676
+
677
+ // --- Authentication Module ---
678
+ auth: {
679
+ login: function() {
680
+ const phoneInput = document.getElementById('phone-input');
681
+ const phone = phoneInput.value.trim();
682
+
683
+ if (phone.length < 10) {
684
+ App.ui.showToast('لطفاً شماره موبایل معتبر وارد کنید');
685
+ return;
686
+ }
687
+
688
+ // Simulate API Call
689
+ App.state.user = { phone: phone, name: 'کاربر ' + phone.slice(-4) };
690
+
691
+ App.ui.showToast(`خوش آمدید، ${App.state.user.name}`);
692
+ App.ui.navigate('room-screen');
693
+ }
694
+ },
695
+
696
+ // --- Room Management Module ---
697
+ rooms: {
698
+ openCreateModal: function() {
699
+ document.getElementById('create-room-modal').classList.add('active');
700
+ document.getElementById('new-room-name').focus();
701
+ },
702
+
703
+ closeModal: function() {
704
+ document.getElementById('create-room-modal').classList.remove('active');
705
+ document.getElementById('new-room-name').value = '';
706
+ },
707
+
708
+ createRoom: function() {
709
+ const nameInput = document.getElementById('new-room-name');
710
+ const name = nameInput.value.trim();
711
+
712
+ if (!name) {
713
+ App.ui.showToast('نام اتاق نمی‌تواند خالی باشد');
714
+ return;
715
+ }
716
+
717
+ const newRoom = {
718
+ id: Date.now(),
719
+ name: name,
720
+ lastMsg: 'اتاق ساخته شد',
721
+ time: new Date().toLocaleTimeString('fa-IR', {hour: '2-digit', minute:'2-digit'})
722
+ };
723
+
724
+ App.state.rooms.unshift(newRoom); // Add to top
725
+ App.utils.saveData();
726
+ App.ui.renderRooms();
727
+ App.rooms.closeModal();
728
+ App.ui.showToast('اتاق با موفقیت ساخته شد');
729
+ }
730
+ },
731
+
732
+ // --- Chat Module ---
733
+ chat: {
734
+ sendMessage: function() {
735
+ const input = document.getElementById('message-input');
736
+ const text = input.value.trim();
737
+
738
+ if (!text) return;
739
+
740
+ const msgData = {
741
+ id: Date.now(),
742
+ roomId: App.state.currentRoomId,
743
+ sender: App.state.user.name,
744
+ text: text,
745
+ timestamp: new Date().toISOString(),
746
+ reactions: []
747
+ };
748
+
749
+ // Add to local state
750
+ App.state.messages.push(msgData);
751
+ App.utils.saveData();
752
+
753
+ // Update room metadata
754
+ const roomIndex = App.state.rooms.findIndex(r => r.id === App.state.currentRoomId);
755
+ if (roomIndex > -1) {
756
+ App.state.rooms[roomIndex].lastMsg = text;
757
+ App.state.rooms[roomIndex].time = new Date().toLocaleTimeString('fa-IR', {hour: '2-digit', minute:'2-digit'});
758
+ App.utils.saveData();
759
+ }
760
+
761
+ // Render
762
+ App.ui.renderMessages();
763
+ App.ui.renderRooms(); // Update list preview
764
+ input.value = '';
765
+ App.chat.cancelReply();
766
+ },
767
+
768
+ handleKeyPress: function(e) {
769
+ if (e.key === 'Enter') {
770
+ App.chat.sendMessage();
771
+ }
772
+ },
773
+
774
+ openRoom: function(roomId) {
775
+ App.state.currentRoomId = roomId;
776
+ const room = App.state.rooms.find(r => r.id === roomId);
777
+
778
+ document.getElementById('chat-room-name').innerText = room.name;
779
+ document.getElementById('chat-room-count').innerText = Math.floor(Math.random() * 20 + 5) + ' نفر آنلاین';
780
+
781
+ App.ui.navigate('chat-screen');
782
+ App.ui.renderMessages();
783
+ },
784
+
785
+ renderMessages: function() {
786
+ const container = document.getElementById('chat-messages');
787
+ container.innerHTML = '';
788
+
789
+ const roomMessages = App.state.messages.filter(m => m.roomId === App.state.currentRoomId);
790
+
791
+ if (roomMessages.length === 0) {
792
+ container.innerHTML = '<div style="text-align:center; opacity:0.5; margin-top:20px;">هنوز پیامی وجود ندارد. شروع کنید!</div>';
793
+ return;
794
+ }
795
+
796
+ roomMessages.forEach(msg => {
797
+ const isSent = msg.sender === App.state.user.name;
798
+ const timeString = new Date(msg.timestamp).toLocaleTimeString('fa-IR', {hour: '2-digit', minute:'2-digit'});
799
+
800
+ const msgEl = document.createElement('div');
801
+ msgEl.className = `message ${isSent ? 'sent' : 'received'}`;
802
+ msgEl.innerHTML = `
803
+ ${msg.text}
804
+ <div class="message-meta">
805
+ <span>${timeString}</span>
806
+ <div class="message-actions">
807
+ <button class="action-btn" onclick="App.chat.startReply(${msg.id})" title="پاسخ"><i class="fas fa-reply"></i></button>
808
+ <button class="action-btn" onclick="App.chat.openDeleteModal(${msg.id})" title="حذف"><i class="fas fa-trash"></i></button>
809
+ </div>
810
+ </div>
811
+ `;
812
+
813
+ // Reaction click listener
814
+ msgEl.addEventListener('click', (e) => {
815
+ if(!e.target.closest('.message-actions')) {
816
+ App.chat.showReactionPopup(msg.id);
817
+ }
818
+ });
819
+
820
+ container.appendChild(msgEl);
821
+ });
822
+
823
+ // Scroll to bottom
824
+ container.scrollTop = container.scrollHeight;
825
+ },
826
+
827
+ // Reply Functionality
828
+ startReply: function(msgId) {
829
+ const msg = App.state.messages.find(m => m.id === msgId);
830
+ App.state.replyingTo = msg;
831
+ const preview = document.getElementById('reply-preview');
832
+ const previewText = document.getElementById('reply-text');
833
+
834
+ previewText.innerText = `پاسخ به: ${msg.text}`;
835
+ preview.style.display = 'flex';
836
+ document.getElementById('message-input').focus();
837
+ },
838
+
839
+ cancelReply: function() {
840
+ App.state.replyingTo = null;
841
+ document.getElementById('reply-preview').style.display = 'none';
842
+ },
843
+
844
+ // Delete Functionality
845
+ openDeleteModal: function(msgId) {
846
+ App.state.deletingMessageId = msgId;
847
+ document.getElementById('delete-modal').classList.add('active');
848
+ },
849
+
850
+ closeDeleteModal: function() {
851
+ App.state.deletingMessageId = null;
852
+ document.getElementById('delete-modal').classList.remove('active');
853
+ },
854
+
855
+ confirmDelete: function() {
856
+ if (App.state.deletingMessageId) {
857
+ App.state.messages = App.state.messages.filter(m => m.id !== App.state.deletingMessageId);
858
+ App.utils.saveData();
859
+ App.ui.renderMessages();
860
+ App.ui.showToast('پیام حذف شد');
861
+ }
862
+ App.chat.closeDeleteModal();
863
+ },
864
+
865
+ // Emoji Functionality
866
+ insertEmoji: function(emoji) {
867
+ const input = document.getElementById('message-input');
868
+ input.value += emoji;
869
+ input.focus();
870
+ },
871
+
872
+ showReactionPopup: function(msgId) {
873
+ const emojis = ['👍', '❤️', '😂', '😮', '😢', '😡'];
874
+ const reactionsContainer = document.createElement('div');
875
+ reactionsContainer.style.position = 'absolute';
876
+ reactionsContainer.style.bottom = '20px';
877
+ reactionsContainer.style.left = '50%';
878
+ reactionsContainer.style.transform = 'translateX(-50%)';
879
+ reactionsContainer.style.display = 'flex';
880
+ reactionsContainer.style.gap = '10px';
881
+ reactionsContainer.style.background = 'rgba(0,0,0,0.7)';
882
+ reactionsContainer.style.padding = '10px';
883
+ reactionsContainer.style.borderRadius = '30px';
884
+ reactionsContainer.style.zIndex = '100';
885
+
886
+ emojis.forEach(emoji => {
887
+ const btn = document.createElement('button');
888
+ btn.innerText = emoji;
889
+ btn.style.background = 'none';
890
+ btn.style.border = 'none';
891
+ btn.style.fontSize = '1.5rem';
892
+ btn.style.cursor = 'pointer';
893
+ btn.onclick = () => App.chat.addReaction(msgId, emoji);
894
+ reactionsContainer.appendChild(btn);
895
+ });
896
+
897
+ document.getElementById('chat-screen').appendChild(reactionsContainer);
898
+
899
+ // Remove after 2 seconds
900
+ setTimeout(() => {
901
+ reactionsContainer.remove();
902
+ }, 2000);
903
+ },
904
+
905
+ addReaction: function(msgId, emoji) {
906
+ const msg = App.state.messages.find(m => m.id === msgId);
907
+ if (msg) {
908
+ // Simple reaction logic: just store it for now
909
+ // In a real app, we'd track users
910
+ App.ui.showToast(`واکنش ${emoji} ثبت شد`);
911
+ }
912
+ },
913
+
914
+ copyLink: function() {
915
+ const dummyLink = `${window.location.origin}?room=${App.state.currentRoomId}`;
916
+ navigator.clipboard.writeText(dummyLink).then(() => {
917
+ App.ui.showToast('لینک اتاق کپی شد');
918
+ });
919
+ }
920
+ },
921
+
922
+ // --- UI Module ---
923
+ ui: {
924
+ navigate: function(screenId) {
925
+ document.querySelectorAll('.screen').forEach(s => s.classList.remove('active'));
926
+ document.getElementById(screenId).classList.add('active');
927
+ },
928
+
929
+ renderRooms: function() {
930
+ const container = document.getElementById('rooms-container');
931
+ container.innerHTML = '';
932
+
933
+ App.state.rooms.forEach(room => {
934
+ const card = document.createElement('div');
935
+ card.className = 'room-card';
936
+ card.onclick = () => App.chat.openRoom(room.id);
937
+ card.innerHTML = `
938
+ <div class="room-info">
939
+ <h3>${room.name}</h3>
940
+ <p>${room.lastMsg}</p>
941
+ </div>
942
+ <div style="text-align:left; color:var(--text-muted); font-size:0.8rem;">
943
+ <div>${room.time}</div>
944
+ <i class="fas fa-chevron-left"></i>
945
+ </div>
946
+ `;
947
+ container.appendChild(card);
948
+ });
949
+ },
950
+
951
+ renderMessages: function() {
952
+ App.chat.renderMessages();
953
+ },
954
+
955
+ toggleEmojiPicker: function() {
956
+ const picker = document.getElementById('emoji-picker');
957
+ picker.classList.toggle('active');
958
+ },
959
+
960
+ showToast: function(message) {
961
+ const toast = document.getElementById('toast');
962
+ toast.innerText = message;
963
+ toast.classList.add('show');
964
+ setTimeout(() => {
965
+ toast.classList.remove('show');
966
+ }, 3000);
967
+ }
968
+ },
969
+
970
+ // --- Gestures Module ---
971
+ gestures: {
972
+ init: function() {
973
+ let startX = 0;
974
+ let startY = 0;
975
+ const container = document.querySelector('.app-container');
976
+
977
+ container.addEventListener('touchstart', (e) => {
978
+ startX = e.changedTouches[0].screenX;
979
+ startY = e.changedTouches[0].screenY;
980
+ }, {passive: true});
981
+
982
+ container.addEventListener('touchend', (e) => {
983
+ const endX = e.changedTouches[0].screenX;
984
+ const endY = e.changedTouches[0].screenY;
985
+ const diffX = startX - endX;
986
+ const diffY = startY - endY;
987
+
988
+ // Swipe Right to go back (common mobile pattern)
989
+ if (Math.abs(diffX) > 50 && Math.abs(diffX) > Math.abs(diffY)) {
990
+ if (diffX > 0) {
991
+ // Swipe Right
992
+ if (document.getElementById('chat-screen').classList.contains('active')) {
993
+ App.ui.navigate('room-screen');
994
+ }
995
+ }
996
+ }
997
+ });
998
+ }
999
+ },
1000
+
1001
+ // --- Utilities ---
1002
+ utils: {
1003
+ saveData: function() {
1004
+ localStorage.setItem('chat_rooms', JSON.stringify(App.state.rooms));
1005
+ localStorage.setItem('chat_messages', JSON.stringify(App.state.messages));
1006
+ }
1007
+ }
1008
+ };
1009
+
1010
+ // Start App
1011
+ document.addEventListener('DOMContentLoaded', () => {
1012
+ App.init();
1013
+ });
1014
+
1015
+ </script>
1016
+ </body>
1017
+ </html>