Spaces:
Running
Running
Upload folder using huggingface_hub
Browse files- index.html +166 -87
index.html
CHANGED
|
@@ -9,7 +9,8 @@
|
|
| 9 |
<!-- Persian Font: Vazirmatn -->
|
| 10 |
<link rel="preconnect" href="https://fonts.googleapis.com">
|
| 11 |
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
| 12 |
-
<link href="https://fonts.googleapis.com/css2?family=Vazirmatn:wght@100;300;400;500;700;900&display=swap"
|
|
|
|
| 13 |
|
| 14 |
<!-- Icons -->
|
| 15 |
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
|
|
@@ -108,9 +109,19 @@
|
|
| 108 |
}
|
| 109 |
|
| 110 |
@keyframes float {
|
| 111 |
-
|
| 112 |
-
|
| 113 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 114 |
}
|
| 115 |
|
| 116 |
/* Header */
|
|
@@ -161,7 +172,8 @@
|
|
| 161 |
color: white;
|
| 162 |
}
|
| 163 |
|
| 164 |
-
.theme-toggle,
|
|
|
|
| 165 |
background: var(--glass);
|
| 166 |
border: 1px solid var(--border);
|
| 167 |
color: var(--text);
|
|
@@ -175,7 +187,8 @@
|
|
| 175 |
transition: all 0.3s ease;
|
| 176 |
}
|
| 177 |
|
| 178 |
-
.theme-toggle:hover,
|
|
|
|
| 179 |
background: var(--primary);
|
| 180 |
transform: scale(1.1);
|
| 181 |
}
|
|
@@ -202,8 +215,15 @@
|
|
| 202 |
}
|
| 203 |
|
| 204 |
@keyframes slideUp {
|
| 205 |
-
from {
|
| 206 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 207 |
}
|
| 208 |
|
| 209 |
.auth-header {
|
|
@@ -586,8 +606,15 @@
|
|
| 586 |
}
|
| 587 |
|
| 588 |
@keyframes messagePop {
|
| 589 |
-
from {
|
| 590 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 591 |
}
|
| 592 |
|
| 593 |
.message.sent {
|
|
@@ -707,12 +734,25 @@
|
|
| 707 |
animation: typing 1.4s infinite;
|
| 708 |
}
|
| 709 |
|
| 710 |
-
.typing-dot:nth-child(2) {
|
| 711 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 712 |
|
| 713 |
@keyframes typing {
|
| 714 |
-
|
| 715 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 716 |
}
|
| 717 |
|
| 718 |
/* Chat Input */
|
|
@@ -1028,8 +1068,85 @@
|
|
| 1028 |
}
|
| 1029 |
|
| 1030 |
@keyframes zoomIn {
|
| 1031 |
-
from {
|
| 1032 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1033 |
}
|
| 1034 |
</style>
|
| 1035 |
</head>
|
|
@@ -1147,7 +1264,8 @@
|
|
| 1147 |
<button class="mobile-menu-btn" onclick="toggleSidebar()">
|
| 1148 |
<i class="fas fa-bars"></i>
|
| 1149 |
</button>
|
| 1150 |
-
<div class="room-icon" id="header-icon"
|
|
|
|
| 1151 |
💬
|
| 1152 |
</div>
|
| 1153 |
<div>
|
|
@@ -1180,7 +1298,7 @@
|
|
| 1180 |
|
| 1181 |
<div class="chat-input-container" style="position: relative;">
|
| 1182 |
<div class="emoji-picker" id="emoji-picker"></div>
|
| 1183 |
-
|
| 1184 |
<div class="reply-preview" id="reply-preview">
|
| 1185 |
<div>
|
| 1186 |
<div style="font-size: 0.8rem; color: var(--primary); margin-bottom: 0.25rem;">پاسخ به:</div>
|
|
@@ -1193,7 +1311,7 @@
|
|
| 1193 |
|
| 1194 |
<div class="chat-input-wrapper">
|
| 1195 |
<input type="file" id="file-input" accept="image/*" style="display: none;" onchange="handleImageUpload(event)">
|
| 1196 |
-
|
| 1197 |
<div class="input-actions">
|
| 1198 |
<button class="input-btn" onclick="document.getElementById('file-input').click()" title="افزودن تصویر">
|
| 1199 |
<i class="fas fa-image"></i>
|
|
@@ -1204,7 +1322,7 @@
|
|
| 1204 |
</div>
|
| 1205 |
|
| 1206 |
<input type="text" class="chat-input" id="message-input" placeholder="پیام خود را بنویسید..." onkeypress="handleKeyPress(event)" oninput="handleTyping()">
|
| 1207 |
-
|
| 1208 |
<button class="send-btn" id="send-btn" onclick="sendMessage()">
|
| 1209 |
<i class="fas fa-paper-plane"></i>
|
| 1210 |
</button>
|
|
@@ -1230,6 +1348,18 @@
|
|
| 1230 |
<img src="" alt="تصویر بزرگ" id="modal-image">
|
| 1231 |
</div>
|
| 1232 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1233 |
<script>
|
| 1234 |
// State Management
|
| 1235 |
const state = {
|
|
@@ -1241,11 +1371,26 @@
|
|
| 1241 |
theme: localStorage.getItem('theme') || 'dark',
|
| 1242 |
typingTimeout: null,
|
| 1243 |
replyTo: null,
|
|
|
|
| 1244 |
simulatedUsers: [
|
| 1245 |
{ name: 'علی', avatar: '👨💻', color: '#6366f1' },
|
| 1246 |
{ name: 'مریم', avatar: '👩🎨', color: '#ec4899' },
|
| 1247 |
{ name: 'حسن', avatar: '👨🔬', color: '#10b981' },
|
| 1248 |
{ name: 'سارا', avatar: '👩💼', color: '#f59e0b' }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1249 |
]
|
| 1250 |
};
|
| 1251 |
|
|
@@ -1317,70 +1462,4 @@
|
|
| 1317 |
|
| 1318 |
// Auth Functions
|
| 1319 |
function switchAuthTab(tab) {
|
| 1320 |
-
document.querySelectorAll('.auth-tab').forEach(t => t.classList.remove
|
| 1321 |
-
event.target.classList.add('active');
|
| 1322 |
-
|
| 1323 |
-
if (tab === 'login') {
|
| 1324 |
-
document.getElementById('login-form').style.display = 'block';
|
| 1325 |
-
document.getElementById('register-form').style.display = 'none';
|
| 1326 |
-
} else {
|
| 1327 |
-
document.getElementById('login-form').style.display = 'none';
|
| 1328 |
-
document.getElementById('register-form').style.display = 'block';
|
| 1329 |
-
}
|
| 1330 |
-
}
|
| 1331 |
-
|
| 1332 |
-
function handleAuth(e, type) {
|
| 1333 |
-
e.preventDefault();
|
| 1334 |
-
|
| 1335 |
-
let username, name;
|
| 1336 |
-
if (type === 'login') {
|
| 1337 |
-
username = document.getElementById('login-username').value;
|
| 1338 |
-
name = username;
|
| 1339 |
-
} else {
|
| 1340 |
-
name = document.getElementById('reg-name').value;
|
| 1341 |
-
username = document.getElementById('reg-username').value;
|
| 1342 |
-
}
|
| 1343 |
-
|
| 1344 |
-
state.currentUser = {
|
| 1345 |
-
username,
|
| 1346 |
-
name,
|
| 1347 |
-
avatar: name.charAt(0),
|
| 1348 |
-
id: Date.now()
|
| 1349 |
-
};
|
| 1350 |
-
|
| 1351 |
-
saveToStorage();
|
| 1352 |
-
showChat();
|
| 1353 |
-
showNotification('خوش آمدید', `خوش آمدید ${name}!`);
|
| 1354 |
-
}
|
| 1355 |
-
|
| 1356 |
-
function showChat() {
|
| 1357 |
-
document.getElementById('auth-screen').style.display = 'none';
|
| 1358 |
-
document.getElementById('main-header').style.display = 'flex';
|
| 1359 |
-
document.getElementById('chat-app').style.display = 'block';
|
| 1360 |
-
|
| 1361 |
-
document.getElementById('user-display-name').textContent = state.currentUser.name;
|
| 1362 |
-
document.getElementById('user-avatar').textContent = state.currentUser.avatar;
|
| 1363 |
-
|
| 1364 |
-
initializeRooms();
|
| 1365 |
-
renderRooms();
|
| 1366 |
-
|
| 1367 |
-
if (state.rooms.length > 0 && !state.currentRoom) {
|
| 1368 |
-
switchRoom(state.rooms[0].id);
|
| 1369 |
-
}
|
| 1370 |
-
|
| 1371 |
-
// Start simulation
|
| 1372 |
-
startSimulation();
|
| 1373 |
-
}
|
| 1374 |
-
|
| 1375 |
-
function logout() {
|
| 1376 |
-
state.currentUser = null;
|
| 1377 |
-
state.currentRoom = null;
|
| 1378 |
-
localStorage.removeItem('chat_user');
|
| 1379 |
-
location.reload();
|
| 1380 |
-
}
|
| 1381 |
-
|
| 1382 |
-
// Room Management
|
| 1383 |
-
function initializeRooms() {
|
| 1384 |
-
if (state.rooms.length === 0) {
|
| 1385 |
-
state.rooms = [
|
| 1386 |
-
{ id: 1, name: 'عمومی', icon: '🌍', type
|
|
|
|
| 9 |
<!-- Persian Font: Vazirmatn -->
|
| 10 |
<link rel="preconnect" href="https://fonts.googleapis.com">
|
| 11 |
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
| 12 |
+
<link href="https://fonts.googleapis.com/css2?family=Vazirmatn:wght@100;300;400;500;700;900&display=swap"
|
| 13 |
+
rel="stylesheet">
|
| 14 |
|
| 15 |
<!-- Icons -->
|
| 16 |
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
|
|
|
|
| 109 |
}
|
| 110 |
|
| 111 |
@keyframes float {
|
| 112 |
+
|
| 113 |
+
0%,
|
| 114 |
+
100% {
|
| 115 |
+
transform: translate(0, 0) scale(1);
|
| 116 |
+
}
|
| 117 |
+
|
| 118 |
+
33% {
|
| 119 |
+
transform: translate(30px, -50px) scale(1.1);
|
| 120 |
+
}
|
| 121 |
+
|
| 122 |
+
66% {
|
| 123 |
+
transform: translate(-20px, 20px) scale(0.9);
|
| 124 |
+
}
|
| 125 |
}
|
| 126 |
|
| 127 |
/* Header */
|
|
|
|
| 172 |
color: white;
|
| 173 |
}
|
| 174 |
|
| 175 |
+
.theme-toggle,
|
| 176 |
+
.sound-toggle {
|
| 177 |
background: var(--glass);
|
| 178 |
border: 1px solid var(--border);
|
| 179 |
color: var(--text);
|
|
|
|
| 187 |
transition: all 0.3s ease;
|
| 188 |
}
|
| 189 |
|
| 190 |
+
.theme-toggle:hover,
|
| 191 |
+
.sound-toggle:hover {
|
| 192 |
background: var(--primary);
|
| 193 |
transform: scale(1.1);
|
| 194 |
}
|
|
|
|
| 215 |
}
|
| 216 |
|
| 217 |
@keyframes slideUp {
|
| 218 |
+
from {
|
| 219 |
+
opacity: 0;
|
| 220 |
+
transform: translateY(30px);
|
| 221 |
+
}
|
| 222 |
+
|
| 223 |
+
to {
|
| 224 |
+
opacity: 1;
|
| 225 |
+
transform: translateY(0);
|
| 226 |
+
}
|
| 227 |
}
|
| 228 |
|
| 229 |
.auth-header {
|
|
|
|
| 606 |
}
|
| 607 |
|
| 608 |
@keyframes messagePop {
|
| 609 |
+
from {
|
| 610 |
+
opacity: 0;
|
| 611 |
+
transform: scale(0.8) translateY(20px);
|
| 612 |
+
}
|
| 613 |
+
|
| 614 |
+
to {
|
| 615 |
+
opacity: 1;
|
| 616 |
+
transform: scale(1) translateY(0);
|
| 617 |
+
}
|
| 618 |
}
|
| 619 |
|
| 620 |
.message.sent {
|
|
|
|
| 734 |
animation: typing 1.4s infinite;
|
| 735 |
}
|
| 736 |
|
| 737 |
+
.typing-dot:nth-child(2) {
|
| 738 |
+
animation-delay: 0.2s;
|
| 739 |
+
}
|
| 740 |
+
|
| 741 |
+
.typing-dot:nth-child(3) {
|
| 742 |
+
animation-delay: 0.4s;
|
| 743 |
+
}
|
| 744 |
|
| 745 |
@keyframes typing {
|
| 746 |
+
|
| 747 |
+
0%,
|
| 748 |
+
60%,
|
| 749 |
+
100% {
|
| 750 |
+
transform: translateY(0);
|
| 751 |
+
}
|
| 752 |
+
|
| 753 |
+
30% {
|
| 754 |
+
transform: translateY(-10px);
|
| 755 |
+
}
|
| 756 |
}
|
| 757 |
|
| 758 |
/* Chat Input */
|
|
|
|
| 1068 |
}
|
| 1069 |
|
| 1070 |
@keyframes zoomIn {
|
| 1071 |
+
from {
|
| 1072 |
+
transform: scale(0.5);
|
| 1073 |
+
opacity: 0;
|
| 1074 |
+
}
|
| 1075 |
+
|
| 1076 |
+
to {
|
| 1077 |
+
transform: scale(1);
|
| 1078 |
+
opacity: 1;
|
| 1079 |
+
}
|
| 1080 |
+
}
|
| 1081 |
+
|
| 1082 |
+
/* Edit Modal */
|
| 1083 |
+
.edit-modal {
|
| 1084 |
+
display: none;
|
| 1085 |
+
position: fixed;
|
| 1086 |
+
top: 0;
|
| 1087 |
+
left: 0;
|
| 1088 |
+
width: 100%;
|
| 1089 |
+
height: 100%;
|
| 1090 |
+
background: rgba(0, 0, 0, 0.5);
|
| 1091 |
+
z-index: 4000;
|
| 1092 |
+
justify-content: center;
|
| 1093 |
+
align-items: center;
|
| 1094 |
+
backdrop-filter: blur(5px);
|
| 1095 |
+
}
|
| 1096 |
+
|
| 1097 |
+
.edit-modal.active {
|
| 1098 |
+
display: flex;
|
| 1099 |
+
}
|
| 1100 |
+
|
| 1101 |
+
.edit-box {
|
| 1102 |
+
background: var(--surface);
|
| 1103 |
+
padding: 2rem;
|
| 1104 |
+
border-radius: 1rem;
|
| 1105 |
+
border: 1px solid var(--border);
|
| 1106 |
+
width: 90%;
|
| 1107 |
+
max-width: 500px;
|
| 1108 |
+
}
|
| 1109 |
+
|
| 1110 |
+
.edit-box h3 {
|
| 1111 |
+
margin-bottom: 1rem;
|
| 1112 |
+
}
|
| 1113 |
+
|
| 1114 |
+
.edit-box textarea {
|
| 1115 |
+
width: 100%;
|
| 1116 |
+
padding: 1rem;
|
| 1117 |
+
border: 1px solid var(--border);
|
| 1118 |
+
border-radius: 0.5rem;
|
| 1119 |
+
background: var(--glass);
|
| 1120 |
+
color: var(--text);
|
| 1121 |
+
font-family: inherit;
|
| 1122 |
+
resize: vertical;
|
| 1123 |
+
min-height: 100px;
|
| 1124 |
+
margin-bottom: 1rem;
|
| 1125 |
+
}
|
| 1126 |
+
|
| 1127 |
+
.edit-actions {
|
| 1128 |
+
display: flex;
|
| 1129 |
+
gap: 1rem;
|
| 1130 |
+
}
|
| 1131 |
+
|
| 1132 |
+
.edit-actions button {
|
| 1133 |
+
flex: 1;
|
| 1134 |
+
padding: 0.75rem;
|
| 1135 |
+
border: none;
|
| 1136 |
+
border-radius: 0.5rem;
|
| 1137 |
+
cursor: pointer;
|
| 1138 |
+
font-family: inherit;
|
| 1139 |
+
font-weight: 700;
|
| 1140 |
+
}
|
| 1141 |
+
|
| 1142 |
+
.btn-save {
|
| 1143 |
+
background: var(--primary);
|
| 1144 |
+
color: white;
|
| 1145 |
+
}
|
| 1146 |
+
|
| 1147 |
+
.btn-cancel {
|
| 1148 |
+
background: var(--glass);
|
| 1149 |
+
color: var(--text);
|
| 1150 |
}
|
| 1151 |
</style>
|
| 1152 |
</head>
|
|
|
|
| 1264 |
<button class="mobile-menu-btn" onclick="toggleSidebar()">
|
| 1265 |
<i class="fas fa-bars"></i>
|
| 1266 |
</button>
|
| 1267 |
+
<div class="room-icon" id="header-icon"
|
| 1268 |
+
style="width: 45px; height: 45px; border-radius: 1rem; background: var(--glass); display: flex; align-items: center; justify-content: center; font-size: 1.25rem;">
|
| 1269 |
💬
|
| 1270 |
</div>
|
| 1271 |
<div>
|
|
|
|
| 1298 |
|
| 1299 |
<div class="chat-input-container" style="position: relative;">
|
| 1300 |
<div class="emoji-picker" id="emoji-picker"></div>
|
| 1301 |
+
|
| 1302 |
<div class="reply-preview" id="reply-preview">
|
| 1303 |
<div>
|
| 1304 |
<div style="font-size: 0.8rem; color: var(--primary); margin-bottom: 0.25rem;">پاسخ به:</div>
|
|
|
|
| 1311 |
|
| 1312 |
<div class="chat-input-wrapper">
|
| 1313 |
<input type="file" id="file-input" accept="image/*" style="display: none;" onchange="handleImageUpload(event)">
|
| 1314 |
+
|
| 1315 |
<div class="input-actions">
|
| 1316 |
<button class="input-btn" onclick="document.getElementById('file-input').click()" title="افزودن تصویر">
|
| 1317 |
<i class="fas fa-image"></i>
|
|
|
|
| 1322 |
</div>
|
| 1323 |
|
| 1324 |
<input type="text" class="chat-input" id="message-input" placeholder="پیام خود را بنویسید..." onkeypress="handleKeyPress(event)" oninput="handleTyping()">
|
| 1325 |
+
|
| 1326 |
<button class="send-btn" id="send-btn" onclick="sendMessage()">
|
| 1327 |
<i class="fas fa-paper-plane"></i>
|
| 1328 |
</button>
|
|
|
|
| 1348 |
<img src="" alt="تصویر بزرگ" id="modal-image">
|
| 1349 |
</div>
|
| 1350 |
|
| 1351 |
+
<!-- Edit Modal -->
|
| 1352 |
+
<div class="edit-modal" id="edit-modal">
|
| 1353 |
+
<div class="edit-box">
|
| 1354 |
+
<h3>ویرایش پیام</h3>
|
| 1355 |
+
<textarea id="edit-textarea"></textarea>
|
| 1356 |
+
<div class="edit-actions">
|
| 1357 |
+
<button class="btn-save" onclick="saveEdit()">ذخیره</button>
|
| 1358 |
+
<button class="btn-cancel" onclick="closeEditModal()">انصراف</button>
|
| 1359 |
+
</div>
|
| 1360 |
+
</div>
|
| 1361 |
+
</div>
|
| 1362 |
+
|
| 1363 |
<script>
|
| 1364 |
// State Management
|
| 1365 |
const state = {
|
|
|
|
| 1371 |
theme: localStorage.getItem('theme') || 'dark',
|
| 1372 |
typingTimeout: null,
|
| 1373 |
replyTo: null,
|
| 1374 |
+
editingMessageId: null,
|
| 1375 |
simulatedUsers: [
|
| 1376 |
{ name: 'علی', avatar: '👨💻', color: '#6366f1' },
|
| 1377 |
{ name: 'مریم', avatar: '👩🎨', color: '#ec4899' },
|
| 1378 |
{ name: 'حسن', avatar: '👨🔬', color: '#10b981' },
|
| 1379 |
{ name: 'سارا', avatar: '👩💼', color: '#f59e0b' }
|
| 1380 |
+
],
|
| 1381 |
+
autoResponses: [
|
| 1382 |
+
'جالب بود! 👍',
|
| 1383 |
+
'متوجه شدم',
|
| 1384 |
+
'حتماً',
|
| 1385 |
+
'میتونی بیشتر توضیح بدی؟',
|
| 1386 |
+
'خیلی عالیه! 🎉',
|
| 1387 |
+
'باشه، فهمیدم',
|
| 1388 |
+
'جالب میگه 😄',
|
| 1389 |
+
'کاملاً موافقم',
|
| 1390 |
+
'بذار فکر کنم...',
|
| 1391 |
+
'واقعاً؟! 😮',
|
| 1392 |
+
'خیلی خوبه',
|
| 1393 |
+
'ممنون که گفتی'
|
| 1394 |
]
|
| 1395 |
};
|
| 1396 |
|
|
|
|
| 1462 |
|
| 1463 |
// Auth Functions
|
| 1464 |
function switchAuthTab(tab) {
|
| 1465 |
+
document.querySelectorAll('.auth-tab').forEach(t => t.classList.remove
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|