Spaces:
Running
Running
Update index.html
Browse files- index.html +87 -69
index.html
CHANGED
|
@@ -3,7 +3,7 @@
|
|
| 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>
|
| 7 |
<link rel="preconnect" href="https://fonts.googleapis.com">
|
| 8 |
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
| 9 |
<link href="https://fonts.googleapis.com/css2?family=Vazirmatn:wght@300;400;500;700&display=swap" rel="stylesheet">
|
|
@@ -113,7 +113,24 @@
|
|
| 113 |
|
| 114 |
.message-content {
|
| 115 |
padding: 10px 15px; border-radius: 20px;
|
|
|
|
|
|
|
| 116 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 117 |
.message-content a {
|
| 118 |
color: var(--eye-color);
|
| 119 |
text-decoration: none;
|
|
@@ -138,6 +155,7 @@
|
|
| 138 |
}
|
| 139 |
|
| 140 |
.bot-message.thinking .message-content { animation: pulse 1.5s infinite; }
|
|
|
|
| 141 |
|
| 142 |
@keyframes pulse {
|
| 143 |
0% { background-color: rgba(255, 255, 255, 0.05); }
|
|
@@ -271,6 +289,34 @@
|
|
| 271 |
|
| 272 |
#send-button.dragging { transition: none; }
|
| 273 |
#send-button svg { width: 24px; height: 24px; stroke: var(--background-dark); stroke-width: 2.5; }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 274 |
|
| 275 |
.site-footer { flex-shrink: 0; text-align: center; padding: 0 15px 10px 15px; }
|
| 276 |
|
|
@@ -314,6 +360,8 @@
|
|
| 314 |
<div id="chat-container"></div>
|
| 315 |
<div id="input-area">
|
| 316 |
<div id="send-button-container">
|
|
|
|
|
|
|
| 317 |
<div id="send-button">
|
| 318 |
<svg viewBox="0 0 24 24" fill="none" stroke-linecap="round" stroke-linejoin="round"><path d="M12 5v14m7-7l-7 7-7-7"/></svg>
|
| 319 |
</div>
|
|
@@ -327,8 +375,8 @@
|
|
| 327 |
</div>
|
| 328 |
<div id="orientation-warning">
|
| 329 |
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M16 4h2a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2h-2M8 20H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2"/><path d="M12 16a4 4 0 1 0 0-8 4 4 0 0 0 0 8Z"/><path d="M12 4v4"/><path d="M12 20v-4"/></svg>
|
| 330 |
-
<h2
|
| 331 |
-
<p>این برنامه برای نمایش
|
| 332 |
</div>
|
| 333 |
|
| 334 |
<script>
|
|
@@ -339,23 +387,20 @@ class RobotFace {
|
|
| 339 |
this.lookX = 0; this.lookY = 0; this.targetLookX = 0; this.targetLookY = 0;
|
| 340 |
this.blinkProgress = 1; this.isBlinking = false; this.lastBlinkTime = Date.now();
|
| 341 |
this.isSleeping = true; this.lastInteractionTime = Date.now(); this.sleepTimeout = 10000;
|
| 342 |
-
this.
|
|
|
|
| 343 |
this.readingOscillation = 0;
|
| 344 |
-
|
| 345 |
-
// --- State variables for new animations ---
|
| 346 |
this.thinkingStartTime = 0;
|
| 347 |
this.leftEyeScale = 1;
|
| 348 |
this.rightEyeScale = 1;
|
| 349 |
|
| 350 |
-
this.isFocusing = false;
|
| 351 |
-
this.focusProgress = 0;
|
| 352 |
-
this.focusEye = 'left';
|
| 353 |
-
this.lastFocusTime = Date.now();
|
| 354 |
-
this.nextFocusDelay = 4000 + Math.random() * 3000;
|
| 355 |
-
|
| 356 |
this.initInteractions(); requestAnimationFrame(this.render.bind(this));
|
| 357 |
}
|
| 358 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 359 |
render() {
|
| 360 |
this.lookX += (this.targetLookX - this.lookX) * 0.1;
|
| 361 |
this.lookY += (this.targetLookY - this.lookY) * 0.1;
|
|
@@ -365,29 +410,26 @@ class RobotFace {
|
|
| 365 |
if (this.isSleeping) {
|
| 366 |
this.drawSleepEyes();
|
| 367 |
} else {
|
| 368 |
-
|
| 369 |
-
const isIdle = !this.isThinking && !this.isWatchingInput && !this.isBlinking && !this.isFocusing;
|
| 370 |
|
| 371 |
if (this.isThinking) {
|
| 372 |
const elapsed = now - this.thinkingStartTime;
|
| 373 |
-
const oscillation = Math.sin(elapsed / 300);
|
| 374 |
-
const scaleAmount = 0.3;
|
| 375 |
this.leftEyeScale = 1 - (scaleAmount * (oscillation + 1) / 2);
|
| 376 |
this.rightEyeScale = 1 - (scaleAmount * (-oscillation + 1) / 2);
|
| 377 |
} else {
|
| 378 |
-
// Reset scale if not thinking
|
| 379 |
this.leftEyeScale = 1;
|
| 380 |
this.rightEyeScale = 1;
|
| 381 |
}
|
| 382 |
|
| 383 |
-
if (this.
|
| 384 |
this.targetLookY = 25; this.readingOscillation += 0.1;
|
| 385 |
this.targetLookX = Math.sin(this.readingOscillation) * 10;
|
| 386 |
}
|
| 387 |
|
| 388 |
if (isIdle && now - this.lastInteractionTime > this.sleepTimeout) { this.isSleeping = true; }
|
| 389 |
if (isIdle && now - this.lastBlinkTime > 3000 + Math.random() * 2000) { this.blink(); }
|
| 390 |
-
if (isIdle && now - this.lastFocusTime > this.nextFocusDelay) { this.startFocus(); }
|
| 391 |
|
| 392 |
this.drawExpression();
|
| 393 |
}
|
|
@@ -397,55 +439,16 @@ class RobotFace {
|
|
| 397 |
drawExpression() {
|
| 398 |
const eW = 100, eH = 100, eR = 30, eY = this.H / 2 + this.lookY;
|
| 399 |
const lCX = this.W * 0.3 + this.lookX, rCX = this.W * 0.7 + this.lookX;
|
| 400 |
-
|
| 401 |
-
let finalLeftScale = this.leftEyeScale;
|
| 402 |
-
let finalRightScale = this.rightEyeScale;
|
| 403 |
-
|
| 404 |
-
if (this.isFocusing) {
|
| 405 |
-
const scale = 1 - (1 - 0.65) * this.focusProgress;
|
| 406 |
-
if (this.focusEye === 'left') {
|
| 407 |
-
finalLeftScale = scale;
|
| 408 |
-
} else {
|
| 409 |
-
finalRightScale = scale;
|
| 410 |
-
}
|
| 411 |
-
}
|
| 412 |
|
| 413 |
-
const lW = eW *
|
| 414 |
-
const lH = eH * this.blinkProgress *
|
| 415 |
-
const rW = eW *
|
| 416 |
-
const rH = eH * this.blinkProgress *
|
| 417 |
|
| 418 |
this.drawEye(lCX, eY, lW, lH, eR);
|
| 419 |
this.drawEye(rCX, eY, rW, rH, eR);
|
| 420 |
}
|
| 421 |
|
| 422 |
-
startFocus() {
|
| 423 |
-
if (this.isFocusing) return;
|
| 424 |
-
this.isFocusing = true;
|
| 425 |
-
this.focusEye = Math.random() < 0.5 ? 'left' : 'right';
|
| 426 |
-
this.lastFocusTime = Date.now();
|
| 427 |
-
this.nextFocusDelay = 4000 + Math.random() * 3000;
|
| 428 |
-
|
| 429 |
-
let startTime = null;
|
| 430 |
-
const duration = 300; // a quick focus animation
|
| 431 |
-
const animateFocus = (timestamp) => {
|
| 432 |
-
if (!startTime) startTime = timestamp;
|
| 433 |
-
const elapsed = timestamp - startTime;
|
| 434 |
-
|
| 435 |
-
if (elapsed < duration) { // Focusing in
|
| 436 |
-
this.focusProgress = elapsed / duration;
|
| 437 |
-
} else if (elapsed < duration * 2) { // Focusing out
|
| 438 |
-
this.focusProgress = 1 - ((elapsed - duration) / duration);
|
| 439 |
-
} else {
|
| 440 |
-
this.focusProgress = 0;
|
| 441 |
-
this.isFocusing = false;
|
| 442 |
-
return;
|
| 443 |
-
}
|
| 444 |
-
requestAnimationFrame(animateFocus);
|
| 445 |
-
};
|
| 446 |
-
requestAnimationFrame(animateFocus);
|
| 447 |
-
}
|
| 448 |
-
|
| 449 |
startThinking() {
|
| 450 |
this.isThinking = true;
|
| 451 |
this.thinkingStartTime = Date.now();
|
|
@@ -458,7 +461,6 @@ class RobotFace {
|
|
| 458 |
this.rightEyeScale = 1;
|
| 459 |
}
|
| 460 |
|
| 461 |
-
// --- Other methods (drawFaceplate, drawEye, drawSleepEyes, initInteractions, wakeUp, blink) remain unchanged ---
|
| 462 |
drawFaceplate() {
|
| 463 |
const c = this.ctx, r = 60;
|
| 464 |
c.fillStyle = '#050505'; c.strokeStyle = '#333333'; c.lineWidth = 4;
|
|
@@ -487,7 +489,7 @@ class RobotFace {
|
|
| 487 |
}
|
| 488 |
initInteractions() {
|
| 489 |
const onMove = e => {
|
| 490 |
-
if (this.isSleeping || this.
|
| 491 |
this.wakeUp(); const max = 15;
|
| 492 |
const bcr = document.body.getBoundingClientRect();
|
| 493 |
const clientX = e.clientX || e.touches?.[0]?.clientX || 0;
|
|
@@ -524,7 +526,9 @@ class ChatInterface {
|
|
| 524 |
this.inputArea = document.getElementById('input-area');
|
| 525 |
this.sendButtonContainer = document.getElementById('send-button-container');
|
| 526 |
this.sendButton = document.getElementById('send-button');
|
|
|
|
| 527 |
this.isDragging = false; this.startY = 0; this.currentY = 0; this.dragThreshold = 30;
|
|
|
|
| 528 |
this.API_URL = 'https://text.pollinations.ai/openai';
|
| 529 |
|
| 530 |
const SYSTEM_PROMPT = `
|
|
@@ -562,6 +566,9 @@ class ChatInterface {
|
|
| 562 |
this.input.addEventListener('input', () => {
|
| 563 |
this.input.style.height = 'auto';
|
| 564 |
this.input.style.height = (this.input.scrollHeight) + 'px';
|
|
|
|
|
|
|
|
|
|
| 565 |
if (this.input.value.trim() !== '') {
|
| 566 |
this.inputArea.classList.add('typing');
|
| 567 |
} else {
|
|
@@ -569,10 +576,10 @@ class ChatInterface {
|
|
| 569 |
}
|
| 570 |
});
|
| 571 |
this.input.addEventListener('focus', () => {
|
| 572 |
-
this.robotFace.
|
| 573 |
setTimeout(() => { document.getElementById('input-area').scrollIntoView({ behavior: 'smooth', block: 'end' }); }, 300);
|
| 574 |
});
|
| 575 |
-
this.input.addEventListener('blur', () => { this.robotFace.
|
| 576 |
this.sendButtonContainer.addEventListener('mousedown', this.dragStart.bind(this));
|
| 577 |
this.sendButtonContainer.addEventListener('touchstart', this.dragStart.bind(this), { passive: true });
|
| 578 |
window.addEventListener('mousemove', this.dragMove.bind(this));
|
|
@@ -597,9 +604,19 @@ class ChatInterface {
|
|
| 597 |
}
|
| 598 |
dragEnd() {
|
| 599 |
if (!this.isDragging) return;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 600 |
this.isDragging = false; this.sendButton.classList.remove('dragging');
|
| 601 |
this.sendButtonContainer.style.cursor = 'grab';
|
| 602 |
-
if (this.currentY > this.dragThreshold) { this.sendMessage(this.input.value); }
|
| 603 |
this.sendButton.style.top = '10px'; this.currentY = 0;
|
| 604 |
}
|
| 605 |
|
|
@@ -611,6 +628,7 @@ class ChatInterface {
|
|
| 611 |
this.conversationHistory.push({ role: 'user', content: text });
|
| 612 |
this.input.value = ''; this.input.style.height = 'auto';
|
| 613 |
this.inputArea.classList.remove('typing');
|
|
|
|
| 614 |
|
| 615 |
this.robotFace.startThinking();
|
| 616 |
const thinkingBubble = this.addMessage('...', 'bot', true);
|
|
@@ -625,9 +643,9 @@ class ChatInterface {
|
|
| 625 |
this.addMessage(botReply, 'bot');
|
| 626 |
|
| 627 |
} catch (error) {
|
| 628 |
-
console.error("
|
| 629 |
thinkingBubble.remove();
|
| 630 |
-
this.addMessage(
|
| 631 |
} finally {
|
| 632 |
this.robotFace.stopThinking();
|
| 633 |
}
|
|
|
|
| 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>ROBO☬SHΞN™</title>
|
| 7 |
<link rel="preconnect" href="https://fonts.googleapis.com">
|
| 8 |
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
| 9 |
<link href="https://fonts.googleapis.com/css2?family=Vazirmatn:wght@300;400;500;700&display=swap" rel="stylesheet">
|
|
|
|
| 113 |
|
| 114 |
.message-content {
|
| 115 |
padding: 10px 15px; border-radius: 20px;
|
| 116 |
+
position: relative;
|
| 117 |
+
overflow: hidden;
|
| 118 |
}
|
| 119 |
+
.message-content::before {
|
| 120 |
+
content: '';
|
| 121 |
+
position: absolute;
|
| 122 |
+
top: 0;
|
| 123 |
+
left: -150%;
|
| 124 |
+
width: 100%;
|
| 125 |
+
height: 100%;
|
| 126 |
+
background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.1), transparent);
|
| 127 |
+
transform: skewX(-25deg);
|
| 128 |
+
animation: sheen 4s infinite;
|
| 129 |
+
}
|
| 130 |
+
@keyframes sheen {
|
| 131 |
+
100% { left: 150%; }
|
| 132 |
+
}
|
| 133 |
+
|
| 134 |
.message-content a {
|
| 135 |
color: var(--eye-color);
|
| 136 |
text-decoration: none;
|
|
|
|
| 155 |
}
|
| 156 |
|
| 157 |
.bot-message.thinking .message-content { animation: pulse 1.5s infinite; }
|
| 158 |
+
.bot-message.thinking .message-content::before { display: none; }
|
| 159 |
|
| 160 |
@keyframes pulse {
|
| 161 |
0% { background-color: rgba(255, 255, 255, 0.05); }
|
|
|
|
| 289 |
|
| 290 |
#send-button.dragging { transition: none; }
|
| 291 |
#send-button svg { width: 24px; height: 24px; stroke: var(--background-dark); stroke-width: 2.5; }
|
| 292 |
+
|
| 293 |
+
#send-hint {
|
| 294 |
+
position: absolute;
|
| 295 |
+
bottom: 100%;
|
| 296 |
+
left: 50%;
|
| 297 |
+
transform: translateX(50%);
|
| 298 |
+
margin-bottom: 5px;
|
| 299 |
+
background-color: #222;
|
| 300 |
+
color: var(--eye-color);
|
| 301 |
+
padding: 5px 10px;
|
| 302 |
+
border-radius: 8px;
|
| 303 |
+
font-size: 12px;
|
| 304 |
+
opacity: 0;
|
| 305 |
+
pointer-events: none;
|
| 306 |
+
transition: opacity 0.3s;
|
| 307 |
+
white-space: nowrap;
|
| 308 |
+
}
|
| 309 |
+
#send-hint.show {
|
| 310 |
+
opacity: 1;
|
| 311 |
+
animation: blink-fade 3s forwards;
|
| 312 |
+
}
|
| 313 |
+
@keyframes blink-fade {
|
| 314 |
+
0%, 100% { opacity: 0; }
|
| 315 |
+
10%, 30%, 50% { opacity: 1; }
|
| 316 |
+
20%, 40% { opacity: 0.5; }
|
| 317 |
+
60% { opacity: 1; }
|
| 318 |
+
}
|
| 319 |
+
|
| 320 |
|
| 321 |
.site-footer { flex-shrink: 0; text-align: center; padding: 0 15px 10px 15px; }
|
| 322 |
|
|
|
|
| 360 |
<div id="chat-container"></div>
|
| 361 |
<div id="input-area">
|
| 362 |
<div id="send-button-container">
|
| 363 |
+
<!-- اصلاح کلیدی: راهنما به داخل کانتینر دکمه منتقل شد -->
|
| 364 |
+
<div id="send-hint">بکش پایین رها کن</div>
|
| 365 |
<div id="send-button">
|
| 366 |
<svg viewBox="0 0 24 24" fill="none" stroke-linecap="round" stroke-linejoin="round"><path d="M12 5v14m7-7l-7 7-7-7"/></svg>
|
| 367 |
</div>
|
|
|
|
| 375 |
</div>
|
| 376 |
<div id="orientation-warning">
|
| 377 |
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M16 4h2a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2h-2M8 20H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2"/><path d="M12 16a4 4 0 1 0 0-8 4 4 0 0 0 0 8Z"/><path d="M12 4v4"/><path d="M12 20v-4"/></svg>
|
| 378 |
+
<h2>فورا راست کن گوشی ضمنا رو سیستم هم آنتن نمیده </h2>
|
| 379 |
+
<p>این برنامه برای نمایش سیخکی تو گوشی طراحی شده .</p>
|
| 380 |
</div>
|
| 381 |
|
| 382 |
<script>
|
|
|
|
| 387 |
this.lookX = 0; this.lookY = 0; this.targetLookX = 0; this.targetLookY = 0;
|
| 388 |
this.blinkProgress = 1; this.isBlinking = false; this.lastBlinkTime = Date.now();
|
| 389 |
this.isSleeping = true; this.lastInteractionTime = Date.now(); this.sleepTimeout = 10000;
|
| 390 |
+
this.isTyping = false;
|
| 391 |
+
this.isThinking = false;
|
| 392 |
this.readingOscillation = 0;
|
|
|
|
|
|
|
| 393 |
this.thinkingStartTime = 0;
|
| 394 |
this.leftEyeScale = 1;
|
| 395 |
this.rightEyeScale = 1;
|
| 396 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 397 |
this.initInteractions(); requestAnimationFrame(this.render.bind(this));
|
| 398 |
}
|
| 399 |
|
| 400 |
+
setTyping(isTyping) {
|
| 401 |
+
this.isTyping = isTyping;
|
| 402 |
+
}
|
| 403 |
+
|
| 404 |
render() {
|
| 405 |
this.lookX += (this.targetLookX - this.lookX) * 0.1;
|
| 406 |
this.lookY += (this.targetLookY - this.lookY) * 0.1;
|
|
|
|
| 410 |
if (this.isSleeping) {
|
| 411 |
this.drawSleepEyes();
|
| 412 |
} else {
|
| 413 |
+
const isIdle = !this.isThinking && !this.isTyping && !this.isBlinking;
|
|
|
|
| 414 |
|
| 415 |
if (this.isThinking) {
|
| 416 |
const elapsed = now - this.thinkingStartTime;
|
| 417 |
+
const oscillation = Math.sin(elapsed / 300);
|
| 418 |
+
const scaleAmount = 0.3;
|
| 419 |
this.leftEyeScale = 1 - (scaleAmount * (oscillation + 1) / 2);
|
| 420 |
this.rightEyeScale = 1 - (scaleAmount * (-oscillation + 1) / 2);
|
| 421 |
} else {
|
|
|
|
| 422 |
this.leftEyeScale = 1;
|
| 423 |
this.rightEyeScale = 1;
|
| 424 |
}
|
| 425 |
|
| 426 |
+
if (this.isTyping) {
|
| 427 |
this.targetLookY = 25; this.readingOscillation += 0.1;
|
| 428 |
this.targetLookX = Math.sin(this.readingOscillation) * 10;
|
| 429 |
}
|
| 430 |
|
| 431 |
if (isIdle && now - this.lastInteractionTime > this.sleepTimeout) { this.isSleeping = true; }
|
| 432 |
if (isIdle && now - this.lastBlinkTime > 3000 + Math.random() * 2000) { this.blink(); }
|
|
|
|
| 433 |
|
| 434 |
this.drawExpression();
|
| 435 |
}
|
|
|
|
| 439 |
drawExpression() {
|
| 440 |
const eW = 100, eH = 100, eR = 30, eY = this.H / 2 + this.lookY;
|
| 441 |
const lCX = this.W * 0.3 + this.lookX, rCX = this.W * 0.7 + this.lookX;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 442 |
|
| 443 |
+
const lW = eW * this.leftEyeScale;
|
| 444 |
+
const lH = eH * this.blinkProgress * this.leftEyeScale;
|
| 445 |
+
const rW = eW * this.rightEyeScale;
|
| 446 |
+
const rH = eH * this.blinkProgress * this.rightEyeScale;
|
| 447 |
|
| 448 |
this.drawEye(lCX, eY, lW, lH, eR);
|
| 449 |
this.drawEye(rCX, eY, rW, rH, eR);
|
| 450 |
}
|
| 451 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 452 |
startThinking() {
|
| 453 |
this.isThinking = true;
|
| 454 |
this.thinkingStartTime = Date.now();
|
|
|
|
| 461 |
this.rightEyeScale = 1;
|
| 462 |
}
|
| 463 |
|
|
|
|
| 464 |
drawFaceplate() {
|
| 465 |
const c = this.ctx, r = 60;
|
| 466 |
c.fillStyle = '#050505'; c.strokeStyle = '#333333'; c.lineWidth = 4;
|
|
|
|
| 489 |
}
|
| 490 |
initInteractions() {
|
| 491 |
const onMove = e => {
|
| 492 |
+
if (this.isSleeping || this.isTyping || this.isThinking) return;
|
| 493 |
this.wakeUp(); const max = 15;
|
| 494 |
const bcr = document.body.getBoundingClientRect();
|
| 495 |
const clientX = e.clientX || e.touches?.[0]?.clientX || 0;
|
|
|
|
| 526 |
this.inputArea = document.getElementById('input-area');
|
| 527 |
this.sendButtonContainer = document.getElementById('send-button-container');
|
| 528 |
this.sendButton = document.getElementById('send-button');
|
| 529 |
+
this.sendHint = document.getElementById('send-hint');
|
| 530 |
this.isDragging = false; this.startY = 0; this.currentY = 0; this.dragThreshold = 30;
|
| 531 |
+
this.typingTimeout = null; this.hintTimeout = null;
|
| 532 |
this.API_URL = 'https://text.pollinations.ai/openai';
|
| 533 |
|
| 534 |
const SYSTEM_PROMPT = `
|
|
|
|
| 566 |
this.input.addEventListener('input', () => {
|
| 567 |
this.input.style.height = 'auto';
|
| 568 |
this.input.style.height = (this.input.scrollHeight) + 'px';
|
| 569 |
+
this.robotFace.setTyping(true);
|
| 570 |
+
clearTimeout(this.typingTimeout);
|
| 571 |
+
this.typingTimeout = setTimeout(() => { this.robotFace.setTyping(false); }, 1000);
|
| 572 |
if (this.input.value.trim() !== '') {
|
| 573 |
this.inputArea.classList.add('typing');
|
| 574 |
} else {
|
|
|
|
| 576 |
}
|
| 577 |
});
|
| 578 |
this.input.addEventListener('focus', () => {
|
| 579 |
+
this.robotFace.wakeUp();
|
| 580 |
setTimeout(() => { document.getElementById('input-area').scrollIntoView({ behavior: 'smooth', block: 'end' }); }, 300);
|
| 581 |
});
|
| 582 |
+
this.input.addEventListener('blur', () => { this.robotFace.setTyping(false); });
|
| 583 |
this.sendButtonContainer.addEventListener('mousedown', this.dragStart.bind(this));
|
| 584 |
this.sendButtonContainer.addEventListener('touchstart', this.dragStart.bind(this), { passive: true });
|
| 585 |
window.addEventListener('mousemove', this.dragMove.bind(this));
|
|
|
|
| 604 |
}
|
| 605 |
dragEnd() {
|
| 606 |
if (!this.isDragging) return;
|
| 607 |
+
|
| 608 |
+
if (this.currentY > this.dragThreshold) {
|
| 609 |
+
this.sendMessage(this.input.value);
|
| 610 |
+
} else if (this.currentY < 10 && this.input.value.trim() !== '') {
|
| 611 |
+
clearTimeout(this.hintTimeout);
|
| 612 |
+
this.sendHint.classList.add('show');
|
| 613 |
+
this.hintTimeout = setTimeout(() => {
|
| 614 |
+
this.sendHint.classList.remove('show');
|
| 615 |
+
}, 3000);
|
| 616 |
+
}
|
| 617 |
+
|
| 618 |
this.isDragging = false; this.sendButton.classList.remove('dragging');
|
| 619 |
this.sendButtonContainer.style.cursor = 'grab';
|
|
|
|
| 620 |
this.sendButton.style.top = '10px'; this.currentY = 0;
|
| 621 |
}
|
| 622 |
|
|
|
|
| 628 |
this.conversationHistory.push({ role: 'user', content: text });
|
| 629 |
this.input.value = ''; this.input.style.height = 'auto';
|
| 630 |
this.inputArea.classList.remove('typing');
|
| 631 |
+
this.robotFace.setTyping(false);
|
| 632 |
|
| 633 |
this.robotFace.startThinking();
|
| 634 |
const thinkingBubble = this.addMessage('...', 'bot', true);
|
|
|
|
| 643 |
this.addMessage(botReply, 'bot');
|
| 644 |
|
| 645 |
} catch (error) {
|
| 646 |
+
console.error("سرور در حال دراوردن ادای تنگا میباشد:", error);
|
| 647 |
thinkingBubble.remove();
|
| 648 |
+
this.addMessage(`سرم شلوغه یه دیقه بکش بیرون بعدا بیا: ${error.message}`, 'bot');
|
| 649 |
} finally {
|
| 650 |
this.robotFace.stopThinking();
|
| 651 |
}
|