Mark-Lasfar commited on
Commit
e018b86
·
1 Parent(s): 8fa53e0
Files changed (1) hide show
  1. static/js/chat.js +79 -32
static/js/chat.js CHANGED
@@ -33,33 +33,52 @@ const uiElements = {
33
  settingsModal: document.getElementById('settingsModal'),
34
  closeSettingsBtn: document.getElementById('closeSettingsBtn'),
35
  settingsForm: document.getElementById('settingsForm'),
36
- historyToggle: document.getElementBy AOS.init({
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
37
  duration: 800,
38
  easing: 'ease-out-cubic',
39
  once: true,
40
  offset: 50,
41
  });
42
- if(currentConversationId && checkAuth()) {
 
43
  console.log('Loading conversation with ID:', currentConversationId);
44
- await loadConversation(currentConversationId);
45
  } else if (conversationHistory.length > 0) {
46
- console.log('Restoring conversation history from sessionStorage:', conversationHistory);
47
- enterChatView();
48
- conversationHistory.forEach(msg => {
49
- console.log('Adding message from history:', msg);
50
- addMsg(msg.role, msg.content);
51
- });
52
- } else {
53
- console.log('No conversation history or ID, starting fresh');
54
- }
55
- autoResizeTextarea();
56
- updateSendButtonState();
57
- if (uiElements.swipeHint) {
58
- setTimeout(() => {
59
- uiElements.swipeHint.style.display = 'none';
60
- }, 3000);
61
- }
62
- setupTouchGestures();
 
63
  });
64
 
65
  // Check authentication token
@@ -114,6 +133,13 @@ function renderMarkdown(el) {
114
  });
115
  wrapper.querySelectorAll('hr').forEach(h => h.classList.add('styled-hr'));
116
  Prism.highlightAllUnder(wrapper);
 
 
 
 
 
 
 
117
  }
118
 
119
  // Toggle chat view
@@ -149,8 +175,6 @@ function addMsg(who, text) {
149
  if (uiElements.chatBox) {
150
  uiElements.chatBox.appendChild(div);
151
  uiElements.chatBox.classList.remove('hidden');
152
- uiElements.chatBox.scrollTop = uiElements.chatBox.scrollHeight;
153
- console.log('Message added to chatBox:', div);
154
  } else {
155
  console.error('chatBox is null');
156
  }
@@ -334,6 +358,9 @@ async function sendRequest(endpoint, body, headers = {}) {
334
  return response;
335
  } catch (error) {
336
  console.error('Send request error:', error);
 
 
 
337
  throw error;
338
  }
339
  }
@@ -526,7 +553,10 @@ async function createNewConversation() {
526
  console.error('Error creating conversation:', error);
527
  alert('Failed to create new conversation. Please try again.');
528
  }
529
- if (uiElements.chatBox) uiElements.chatBox.scrollTop = uiElements.chatBox.scrollHeight;
 
 
 
530
  }
531
 
532
  // Update conversation title
@@ -585,9 +615,10 @@ function setupTouchGestures() {
585
  if (!isSidebarOpen) return;
586
  let translateX = Math.max(-uiElements.sidebar.offsetWidth, Math.min(0, e.deltaX));
587
  uiElements.sidebar.style.transform = `translateX(${translateX}px)`;
 
588
  });
589
  hammer.on('panend', e => {
590
- if (!isSidebarOpen) return;
591
  if (e.deltaX < -50) {
592
  toggleSidebar(false);
593
  } else {
@@ -726,7 +757,6 @@ async function submitMessage() {
726
  currentAssistantText = buffer;
727
  streamMsg.querySelector('.loading')?.remove();
728
  renderMarkdown(streamMsg);
729
- if (uiElements.chatBox) uiElements.chatBox.scrollTop = uiElements.chatBox.scrollHeight;
730
  }
731
  }
732
  responseText = buffer;
@@ -744,7 +774,7 @@ async function submitMessage() {
744
  await saveMessageToConversation(currentConversationId, 'assistant', responseText);
745
  }
746
  if (checkAuth()) {
747
- await loadConversations(); // تحديث السايدبار
748
  }
749
  finalizeRequest();
750
  } catch (error) {
@@ -798,8 +828,6 @@ if (logoutBtn) {
798
  });
799
  }
800
 
801
-
802
-
803
  // Settings Modal
804
  if (uiElements.settingsBtn) {
805
  uiElements.settingsBtn.addEventListener('click', async () => {
@@ -989,16 +1017,21 @@ if (uiElements.form) {
989
  }
990
 
991
  if (uiElements.input) {
 
 
 
 
 
 
 
 
 
992
  uiElements.input.addEventListener('keydown', (e) => {
993
  if (e.key === 'Enter' && !e.shiftKey) {
994
  e.preventDefault();
995
  if (!isRecording && !uiElements.sendBtn.disabled) submitMessage();
996
  }
997
  });
998
- uiElements.input.addEventListener('input', () => {
999
- autoResizeTextarea();
1000
- updateSendButtonState();
1001
- });
1002
  }
1003
 
1004
  if (uiElements.stopBtn) {
@@ -1034,3 +1067,17 @@ localStorage.removeItem = function (key) {
1034
  console.log('Removing from localStorage:', key);
1035
  originalRemoveItem.apply(this, arguments);
1036
  };
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
33
  settingsModal: document.getElementById('settingsModal'),
34
  closeSettingsBtn: document.getElementById('closeSettingsBtn'),
35
  settingsForm: document.getElementById('settingsForm'),
36
+ historyToggle: document.getElementById('historyToggle'),
37
+ };
38
+
39
+ // State variables
40
+ let conversationHistory = JSON.parse(sessionStorage.getItem('conversationHistory') || '[]');
41
+ let currentConversationId = window.conversationId || null;
42
+ let currentConversationTitle = window.conversationTitle || null;
43
+ let isRequestActive = false;
44
+ let isRecording = false;
45
+ let mediaRecorder = null;
46
+ let audioChunks = [];
47
+ let streamMsg = null;
48
+ let currentAssistantText = '';
49
+ let isSidebarOpen = window.innerWidth >= 768;
50
+
51
+ // Initialize AOS and load initial conversation
52
+ document.addEventListener('DOMContentLoaded', async () => {
53
+ AOS.init({
54
  duration: 800,
55
  easing: 'ease-out-cubic',
56
  once: true,
57
  offset: 50,
58
  });
59
+
60
+ if (currentConversationId && checkAuth()) {
61
  console.log('Loading conversation with ID:', currentConversationId);
62
+ await loadConversation(currentConversationId);
63
  } else if (conversationHistory.length > 0) {
64
+ console.log('Restoring conversation history from sessionStorage:', conversationHistory);
65
+ enterChatView();
66
+ conversationHistory.forEach(msg => {
67
+ console.log('Adding message from history:', msg);
68
+ addMsg(msg.role, msg.content);
69
+ });
70
+ } else {
71
+ console.log('No conversation history or ID, starting fresh');
72
+ }
73
+
74
+ autoResizeTextarea();
75
+ updateSendButtonState();
76
+ if (uiElements.swipeHint) {
77
+ setTimeout(() => {
78
+ uiElements.swipeHint.style.display = 'none';
79
+ }, 3000);
80
+ }
81
+ setupTouchGestures();
82
  });
83
 
84
  // Check authentication token
 
133
  });
134
  wrapper.querySelectorAll('hr').forEach(h => h.classList.add('styled-hr'));
135
  Prism.highlightAllUnder(wrapper);
136
+ // Smooth scroll to bottom
137
+ if (uiElements.chatBox) {
138
+ uiElements.chatBox.scrollTo({
139
+ top: uiElements.chatBox.scrollHeight,
140
+ behavior: 'smooth',
141
+ });
142
+ }
143
  }
144
 
145
  // Toggle chat view
 
175
  if (uiElements.chatBox) {
176
  uiElements.chatBox.appendChild(div);
177
  uiElements.chatBox.classList.remove('hidden');
 
 
178
  } else {
179
  console.error('chatBox is null');
180
  }
 
358
  return response;
359
  } catch (error) {
360
  console.error('Send request error:', error);
361
+ if (error.name === 'AbortError') {
362
+ throw new Error('Request was aborted');
363
+ }
364
  throw error;
365
  }
366
  }
 
553
  console.error('Error creating conversation:', error);
554
  alert('Failed to create new conversation. Please try again.');
555
  }
556
+ if (uiElements.chatBox) uiElements.chatBox.scrollTo({
557
+ top: uiElements.chatBox.scrollHeight,
558
+ behavior: 'smooth',
559
+ });
560
  }
561
 
562
  // Update conversation title
 
615
  if (!isSidebarOpen) return;
616
  let translateX = Math.max(-uiElements.sidebar.offsetWidth, Math.min(0, e.deltaX));
617
  uiElements.sidebar.style.transform = `translateX(${translateX}px)`;
618
+ uiElements.sidebar.style.transition = 'none';
619
  });
620
  hammer.on('panend', e => {
621
+ uiElements.sidebar.style.transition = 'transform 0.3s ease-in-out';
622
  if (e.deltaX < -50) {
623
  toggleSidebar(false);
624
  } else {
 
757
  currentAssistantText = buffer;
758
  streamMsg.querySelector('.loading')?.remove();
759
  renderMarkdown(streamMsg);
 
760
  }
761
  }
762
  responseText = buffer;
 
774
  await saveMessageToConversation(currentConversationId, 'assistant', responseText);
775
  }
776
  if (checkAuth()) {
777
+ await loadConversations();
778
  }
779
  finalizeRequest();
780
  } catch (error) {
 
828
  });
829
  }
830
 
 
 
831
  // Settings Modal
832
  if (uiElements.settingsBtn) {
833
  uiElements.settingsBtn.addEventListener('click', async () => {
 
1017
  }
1018
 
1019
  if (uiElements.input) {
1020
+ // Add debounce to input event
1021
+ let debounceTimer;
1022
+ uiElements.input.addEventListener('input', () => {
1023
+ clearTimeout(debounceTimer);
1024
+ debounceTimer = setTimeout(() => {
1025
+ autoResizeTextarea();
1026
+ updateSendButtonState();
1027
+ }, 100);
1028
+ });
1029
  uiElements.input.addEventListener('keydown', (e) => {
1030
  if (e.key === 'Enter' && !e.shiftKey) {
1031
  e.preventDefault();
1032
  if (!isRecording && !uiElements.sendBtn.disabled) submitMessage();
1033
  }
1034
  });
 
 
 
 
1035
  }
1036
 
1037
  if (uiElements.stopBtn) {
 
1067
  console.log('Removing from localStorage:', key);
1068
  originalRemoveItem.apply(this, arguments);
1069
  };
1070
+
1071
+ // Offline mode detection
1072
+ window.addEventListener('offline', () => {
1073
+ if (uiElements.messageLimitWarning) {
1074
+ uiElements.messageLimitWarning.classList.remove('hidden');
1075
+ uiElements.messageLimitWarning.textContent = 'You are offline. Some features may be limited.';
1076
+ }
1077
+ });
1078
+
1079
+ window.addEventListener('online', () => {
1080
+ if (uiElements.messageLimitWarning) {
1081
+ uiElements.messageLimitWarning.classList.add('hidden');
1082
+ }
1083
+ });