Test / script. js
Abdfah's picture
Create script. js
b30c060 verified
Raw History Blame Contribute Delete
10.2 kB
// CyberGuard AI Assistant Main Script
document.addEventListener('DOMContentLoaded', function() {
// DOM Elements
const sidebar = document.getElementById('sidebar');
const menuToggle = document.getElementById('menu-toggle');
const chatContainer = document.querySelector('.chat-container');
const userInput = document.getElementById('user-input');
const sendButton = document.getElementById('send-btn');
const chatMessages = document.getElementById('chat-messages');
const typingIndicator = document.getElementById('typing-indicator');
const infoButton = document.getElementById('info-btn');
const infoModal = document.getElementById('info-modal');
const closeModalButtons = document.querySelectorAll('.close-modal');
const languageSelector = document.getElementById('language-selector');
const languageDropdown = document.getElementById('language-dropdown');
const currentLanguageSpan = document.getElementById('current-language');
const languageOptions = document.querySelectorAll('.language-option');
const exampleQueries = document.querySelectorAll('.example-query');
const newChatButtons = document.querySelectorAll('#sidebar-new-chat-btn, #header-new-chat-btn');
const conversationList = document.getElementById('conversation-list');
// App State
const state = {
currentLanguage: CONFIG.app.defaultLanguage,
conversations: [], // All conversations
currentConversationId: null, // Current active conversation ID
loading: false,
systemContext: CONFIG.openai.system_message,
};
// Initialize the application
function init() {
loadConversations();
createNewConversation();
setupEventListeners();
updateUIText();
}
// Setup Event Listeners
function setupEventListeners() {
// Menu toggle
menuToggle.addEventListener('click', toggleSidebar);
// Send message on button click
sendButton.addEventListener('click', sendMessage);
// Send message on Enter key (but allow Shift+Enter for new line)
userInput.addEventListener('keydown', (e) => {
if (e.key === 'Enter' && !e.shiftKey) {
e.preventDefault();
if (!sendButton.disabled) {
sendMessage();
}
}
});
// Enable/disable send button based on input
userInput.addEventListener('input', () => {
sendButton.disabled = userInput.value.trim() === '';
// Auto-resize textarea
userInput.style.height = 'auto';
userInput.style.height = (userInput.scrollHeight) + 'px';
});
// Info button
infoButton.addEventListener('click', () => {
infoModal.classList.add('active');
});
// Close modals
closeModalButtons.forEach(button => {
button.addEventListener('click', (e) => {
e.target.closest('.modal').classList.remove('active');
});
});
// Language selector
languageSelector.addEventListener('click', (e) => {
e.stopPropagation();
languageDropdown.classList.toggle('active');
});
// Close language dropdown when clicking outside
document.addEventListener('click', () => {
languageDropdown.classList.remove('active');
});
// Language selection
languageOptions.forEach(option => {
option.addEventListener('click', (e) => {
const lang = e.target.getAttribute('data-lang');
changeLanguage(lang);
languageDropdown.classList.remove('active');
});
});
// Example queries
exampleQueries.forEach(query => {
query.addEventListener('click', () => {
const queryText = query.getAttribute('data-query');
userInput.value = queryText;
sendButton.disabled = false;
userInput.focus();
sendMessage();
});
});
// New chat button
newChatButtons.forEach(button => {
button.addEventListener('click', () => {
createNewConversation();
if (window.innerWidth <= 768) {
toggleSidebar();
}
});
});
}
// Toggle sidebar
function toggleSidebar() {
sidebar.classList.toggle('active');
chatContainer.classList.toggle('sidebar-open');
}
// Send message to AI
async function sendMessage() {
if (userInput.value.trim() === '' || state.loading) return;
const userMessage = userInput.value.trim();
userInput.value = '';
userInput.style.height = 'auto';
sendButton.disabled = true;
// Auto-detect language from user input
detectAndUpdateLanguage(userMessage);
// Add user message to UI
const userMessageId = 'msg-' + Date.now();
addMessageToUI('user', userMessage, userMessageId);
// Scroll to bottom
scrollToBottom();
// Add to conversation history
addMessageToConversation('user', userMessage);
// Show typing indicator
typingIndicator.classList.add('active');
// Set loading state
state.loading = true;
try {
// Get current conversation
const conversation = state.conversations.find(c => c.id === state.currentConversationId);
// Create messages array for API - including conversation history for context
const messages = [
{ role: "system", content: state.systemContext },
...conversation.messages.map(msg => ({
role: msg.role,
content: msg.content
}))
];
// Call OpenAI API
const response = await callOpenAI(messages);
// Hide typing indicator
typingIndicator.classList.remove('active');
// Parse response
if (response && response.choices && response.choices[0]) {
const botResponse = response.choices[0].message.content;
// Add bot message to UI with typing effect
const botMessageId = 'msg-' + Date.now();
addMessageToUI('bot', '', botMessageId);
// Add bot message to conversation immediately but update UI with typing effect
addMessageToConversation('assistant', botResponse);
// Apply typing effect
await typeMessage(botMessageId, botResponse);
// Update the first message of the conversation as the title if this is a new conversation
if (conversation.messages.length <= 2) {
updateConversationTitle(conversation.id, userMessage);
}
// Save conversations to local storage
saveConversations();
// Update sidebar
updateConversationList();
}
} catch (error) {
console.error('Error sending message:', error);
// Add error message to UI
addMessageToUI('bot', 'Sorry, I encountered an error. Please try again later.');
// Hide typing indicator
typingIndicator.classList.remove('active');
}
// Reset loading state
state.loading = false;
// Enable send button if there's text in the input
sendButton.disabled = userInput.value.trim() === '';
// Scroll to bottom
scrollToBottom();
}
// Add message to UI
function addMessageToUI(role, content, id = null) {
const messageDiv = document.createElement('div');
messageDiv.className = `message ${role}`;
if (id) {
messageDiv.id = id;
}
const avatar = document.createElement('div');
avatar.className = 'message-avatar';
if (role === 'user') {
avatar.innerHTML = '<i class="fas fa-user"></i>';
} else {
avatar.innerHTML = '<i class="fas fa-robot"></i>';
}
const messageContent = document.createElement('div');
messageContent.className = 'message-content';
// Format message content with Markdown-like syntax
if (content) {
// Handle code blocks
content = content.replace(/```([\s\S]*?)```/g, function(match, p1) {
return `<pre>${p1}</pre>`;
});
// Handle bold text
content = content.replace(/\*\*(.*?)\*\*/g, '<strong>$1</strong>');
// Handle italic text
content = content.replace(/\*(.*?)\*/g, '<em>$1</em>');
// Handle line breaks
content = content.replace(/\n/g, '<br>');
messageContent.innerHTML = content;
}
const timestamp = document.createElement('div');
timestamp.className = 'message-time';
timestamp.textContent = new Date().toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' });
messageContent.appendChild(timestamp);
messageDiv.appendChild(avatar);
messageDiv.appendChild(messageContent);
// Remove welcome container if present
const welcomeContainer = document.querySelector('.welcome-container');
if (welcomeContainer) {
welcomeContainer.remove();
}
chatMessages.appendChild(messageDiv);
scrollToBottom();
}
// Type effect for bot messages
async function typeMessage(messageId, content) {
const messageContent = document.querySelector(`#${messageId} .message-content`);