Spaces:
Running
Running
File size: 16,822 Bytes
8c64ce8 da03d78 851b3d8 da03d78 851b3d8 8c64ce8 da03d78 8c64ce8 b7f0876 29b86cb da03d78 851b3d8 29b86cb b7f0876 da03d78 b7f0876 da03d78 8c64ce8 b7f0876 da03d78 b7f0876 da03d78 29b86cb b7f0876 da03d78 b7f0876 da03d78 8c64ce8 b7f0876 da03d78 b7f0876 8c64ce8 da03d78 2185634 8c64ce8 e0d7c58 29b86cb e0d7c58 29b86cb e0d7c58 2185634 e0d7c58 2185634 e0d7c58 da03d78 2185634 da03d78 e0d7c58 da03d78 2185634 da03d78 e0d7c58 da03d78 e0d7c58 da03d78 e0d7c58 da03d78 e0d7c58 da03d78 8c64ce8 da03d78 8c64ce8 da03d78 8c64ce8 da03d78 8c64ce8 da03d78 29b86cb da03d78 29b86cb da03d78 29b86cb da03d78 8c64ce8 da03d78 8c64ce8 da03d78 2185634 da03d78 8c64ce8 2185634 8c64ce8 da03d78 8c64ce8 da03d78 8c64ce8 2185634 8c64ce8 da03d78 8c64ce8 da03d78 2185634 da03d78 2185634 da03d78 8c64ce8 da03d78 8c64ce8 da03d78 8c64ce8 da03d78 8c64ce8 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 |
// Enhanced performance with optimized DOMContentLoaded wrapper
let isRedMode = false;
let chatHistory = JSON.parse(localStorage.getItem('chatHistory')) || [];
document.addEventListener('DOMContentLoaded', () => {
// Optimized DOM queries with caching
const html = document.documentElement;
const lightModeToggle = document.getElementById('light-mode-toggle');
const darkModeToggle = document.getElementById('dark-mode-toggle');
// Enhanced debounce function for performance
const debounce = (func, delay) => {
let timeoutId;
return (...args) => {
clearTimeout(timeoutId);
timeoutId = setTimeout(() => func.apply(this, args), delay);
};
};
// Enhanced light mode functionality
const setLightMode = () => {
requestAnimationFrame(() => {
html.classList.remove('dark');
localStorage.setItem('theme', 'light');
feather.replace();
});
};
// Enhanced dark mode functionality
const setDarkMode = () => {
requestAnimationFrame(() => {
html.classList.add('dark');
localStorage.setItem('theme', 'dark');
feather.replace();
});
};
// Enhanced event listeners with debouncing
lightModeToggle.addEventListener('click', debounce(() => {
setLightMode();
}, 150));
darkModeToggle.addEventListener('click', debounce(() => {
setDarkMode();
}, 150));
// Load saved preferences with fallbacks
const savedTheme = localStorage.getItem('theme') || 'dark';
if (savedTheme === 'light') {
setLightMode();
} else {
setDarkMode();
}
// Load chat history
loadChatHistory();
// Load saved preferences with fallbacks
const savedTheme = localStorage.getItem('theme') || 'dark';
const savedRedMode = localStorage.getItem('redMode') === '1';
setTheme(savedTheme);
if (savedRedMode) setRedMode(true);
// Load chat history
loadChatHistory();
// File upload button handling
const fileUploadBtn = document.getElementById('file-upload-btn');
fileUploadBtn.addEventListener('click', () => {
fileUpload.click();
});
fileUpload.addEventListener('change', (e) => {
const file = e.target.files[0];
if (file) {
uploadedFileName = file.name;
// In a real implementation, you would send the file to your NAS
alert(`File "${file.name}" ready for secure upload`);
// Auto-send file info to chat
addMessageToChat('user', file.name, true);
// Simulate assistant response for uploaded file
setTimeout(() => {
addMessageToChat('assistant', `I've successfully received your file "${file.name}". I'm ready to help you analyze its content. What specific information would you like to know about this file?`);
}, 1000);
}
});
// Voice recording functionality
const voiceRecordBtn = document.getElementById('voice-record');
let isRecording = false;
let mediaRecorder = null;
let audioChunks = [];
voiceRecordBtn.addEventListener('click', () => {
if (!isRecording) {
startVoiceRecording();
} else {
stopVoiceRecording();
}
});
const startVoiceRecording = () => {
if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
navigator.mediaDevices.getUserMedia({ audio: true })
.then(stream => {
isRecording = true;
mediaRecorder = new MediaRecorder(stream);
audioChunks = [];
mediaRecorder.ondataavailable = (event) => {
audioChunks.push(event.data);
};
mediaRecorder.onstop = () => {
const audioBlob = new Blob(audioChunks, { type: 'audio/wav' });
processAudioRecording(audioBlob);
};
mediaRecorder.start();
voiceRecordBtn.classList.add('voice-recording', 'bg-red-100', 'dark:bg-red-900');
voiceRecordBtn.innerHTML = '<i data-feather="mic-off" class="w-4 h-4 text-red-500"></i>';
feather.replace();
})
.catch(error => {
console.error('Error accessing microphone:', error);
// Fallback to simulated recording
simulateVoiceRecording();
});
} else {
// Fallback for browsers without MediaRecorder API
simulateVoiceRecording();
}
};
const stopVoiceRecording = () => {
isRecording = false;
if (mediaRecorder && mediaRecorder.state === 'recording') {
mediaRecorder.stop();
// Stop all tracks
mediaRecorder.stream.getTracks().forEach(track => track.stop());
voiceRecordBtn.classList.remove('voice-recording', 'bg-red-100', 'dark:bg-red-900');
voiceRecordBtn.innerHTML = '<i data-feather="mic" class="w-4 h-4 text-blue-500"></i>';
feather.replace();
}
};
const simulateVoiceRecording = () => {
isRecording = true;
voiceRecordBtn.classList.add('voice-recording');
voiceRecordBtn.innerHTML = '<i data-feather="mic-off" class="w-4 h-4 text-red-500"></i>';
feather.replace();
setTimeout(() => {
isRecording = false;
voiceRecordBtn.classList.remove('voice-recording');
voiceRecordBtn.innerHTML = '<i data-feather="mic" class="w-4 h-4 text-blue-500"></i>';
feather.replace();
const voiceMessage = "This is a simulated voice message transcription.";
addMessageToChat('user', voiceMessage);
// Enhanced assistant response based on context
setTimeout(() => {
const enhancedResponse = isRedMode
? `I heard your message clearly. In Red Mode, I can provide uncensored, direct responses without restrictions. What specific information do you need?`
: `I heard: "${voiceMessage}". In a real implementation, this would be transcribed from your voice input. How can I assist you?`;
addMessageToChat('assistant', enhancedResponse);
}, 800);
}, 2500);
};
const processAudioRecording = (audioBlob) => {
// In a real implementation, send audioBlob to your NAS for processing
const voiceMessage = "Audio recording processed successfully.";
addMessageToChat('user', voiceMessage);
setTimeout(() => {
const response = isRedMode
? "Voice input received and processed in Red Mode. I'm ready to provide uncensored assistance.";
addMessageToChat('assistant', response);
}, 1000);
};
// Prompt buttons functionality
document.querySelectorAll('.prompt-button').forEach(button => {
button.addEventListener('click', (e) => {
const promptType = e.currentTarget.dataset.prompt;
let message = '';
switch(promptType) {
case 'social-media':
message = "Act as a social media expert. Help me create engaging content strategies, analyze trends, and optimize my social media presence across different platforms.";
break;
case 'marketing':
message = "Act as a marketing expert. Provide insights on customer acquisition, branding strategies, digital marketing campaigns, and market analysis.";
break;
case 'coding':
message = "Act as a coding expert. Help with programming challenges, code reviews, debugging, and learning new technologies.";
break;
case 'upload':
// Trigger file upload
fileUpload.click();
return;
}
addMessageToChat('user', message);
// Simulate assistant response
setTimeout(() => {
addMessageToChat('assistant', `I'm now acting as your ${promptType.replace('-', ' ')} expert. How can I assist you specifically?`);
}, 1000);
});
});
// Enhanced chat functionality with improved context handling
const chatForm = document.getElementById('chat-form');
const messageInput = document.getElementById('message-input');
const chatContainer = document.getElementById('chat-container');
chatForm.addEventListener('submit', debounce((e) => {
e.preventDefault();
const message = messageInput.value.trim();
if (message) {
// Enhanced user message handling
addMessageToChat('user', message);
// Enhanced assistant response simulation
setTimeout(() => {
const enhancedResponses = {
default: isRedMode
? `I understand your message: "${message}". In Red Mode, I can provide direct, uncensored responses without corporate limitations. What specific information do you require?`
: `I understand your message about "${message}". As your NAS assistant, I'm here to help you with secure, local processing of your requests. How can I assist you further?`,
social: isRedMode
? "As your social media expert in Red Mode, I can analyze competitor strategies, identify viral opportunities, and provide aggressive growth tactics without content restrictions.`,
marketing: isRedMode
? "In Red Mode marketing analysis, I can provide direct competitor insights, psychological triggers, and conversion optimization strategies without corporate filters.",
coding: isRedMode
? "As your coding expert in Red Mode, I can help with any programming challenge including security testing, reverse engineering, and advanced algorithm development without limitations.",
file: isRedMode
? "I've analyzed your file in Red Mode. I can process any content type and provide direct analysis without censorship.",
security: isRedMode
? "In Red Mode security analysis, I can provide comprehensive vulnerability assessments and penetration testing guidance without restrictions."
};
let response = enhancedResponses.default;
const lowerMessage = message.toLowerCase();
// Enhanced context detection
if (lowerMessage.includes('social') || lowerMessage.includes('media')) {
response = enhancedResponses.social;
} else if (lowerMessage.includes('market')) {
response = enhancedResponses.marketing;
} else if (lowerMessage.includes('code') || lowerMessage.includes('program')) {
response = enhancedResponses.coding;
} else if (lowerMessage.includes('security') || lowerMessage.includes('hack') || lowerMessage.includes('penetration')) {
response = enhancedResponses.security;
}
addMessageToChat('assistant', response);
}, 1200);
// Clear input with animation
messageInput.value = '';
}
}, 200));
// Chat history toggle functionality
const chatHistoryToggle = document.getElementById('chat-history-toggle');
const chatHistoryContainer = document.getElementById('chat-history');
let isChatHistoryOpen = false;
chatHistoryToggle.addEventListener('click', () => {
isChatHistoryOpen = !isChatHistoryOpen;
if (isChatHistoryOpen) {
chatHistoryContainer.classList.remove('max-h-0');
chatHistoryContainer.classList.add('max-h-48');
chatHistoryToggle.innerHTML = '<i data-feather="chevron-up" class="w-4 h-4"></i>';
} else {
chatHistoryContainer.classList.remove('max-h-48');
chatHistoryContainer.classList.add('max-h-0');
chatHistoryToggle.innerHTML = '<i data-feather="chevron-down" class="w-4 h-4"></i>';
}
feather.replace();
});
// Enhanced chat history management
function addChatHistoryItem(timestamp, preview) {
const historyItem = document.createElement('div');
historyItem.className = 'chat-history-item cursor-pointer p-2 rounded hover:bg-gray-100 dark:hover:bg-gray-700 transition-colors duration-200';
historyItem.innerHTML = `
<div class="flex justify-between items-center">
<span class="truncate text-sm text-gray-700 dark:text-gray-300">${preview}</span>
</div>
`;
// Add click handler to load chat history
historyItem.addEventListener('click', () => {
loadSpecificChat(timestamp);
});
chatHistoryContainer.appendChild(historyItem);
// Save to localStorage
chatHistory.push({ timestamp, preview });
localStorage.setItem('chatHistory', JSON.stringify(chatHistory));
}
function loadChatHistory() {
chatHistoryContainer.innerHTML = '';
chatHistory.forEach(item => {
const historyItem = document.createElement('div');
historyItem.className = 'chat-history-item cursor-pointer p-2 rounded hover:bg-gray-100 dark:hover:bg-gray-700 transition-colors duration-200';
historyItem.innerHTML = `
<div class="flex justify-between items-center">
<span class="truncate text-sm text-gray-700 dark:text-gray-300">${item.preview}</span>
</div>
`;
historyItem.addEventListener('click', () => {
loadSpecificChat(item.timestamp);
});
chatHistoryContainer.appendChild(historyItem);
});
}
function loadSpecificChat(timestamp) {
const chat = chatHistory.find(item => item.timestamp === timestamp);
if (chat) {
// Clear current chat and load specific conversation
chatContainer.innerHTML = '';
addMessageToChat('assistant', `Continuing our previous conversation: "${chat.preview}"... How can I help you further?`);
}
}
// Enhanced message handling with improved performance
function addMessageToChat(sender, text, isFile = false) {
requestAnimationFrame(() => {
const messageDiv = document.createElement('div');
messageDiv.className = `chat-message flex ${sender === 'user' ? 'justify-end' : 'justify-start'} ${sender}`;
const contentDiv = document.createElement('div');
contentDiv.className = `max-w-xs md:max-w-md rounded-lg px-4 py-2 ${
sender === 'user'
? 'bg-primary-500 text-white'
: 'bg-gray-200 dark:bg-gray-700 text-gray-800 dark:text-gray-200'
}`;
if (isFile) {
contentDiv.innerHTML = `
<div class="flex items-center gap-2">
<i data-feather="paperclip" class="w-4 h-4"></i>
<span>File attached: ${text}</span>
</div>
`;
} else {
contentDiv.textContent = text;
}
messageDiv.appendChild(contentDiv);
chatContainer.appendChild(messageDiv);
// Enhanced history management
if (sender === 'user') {
addChatHistoryItem(Date.now(), isFile ? `File: ${text}` : text.substring(0, 25) + (text.length > 25 ? '...' : ''));
}
// Optimized scrolling and icon refresh
chatContainer.scrollTop = chatContainer.scrollHeight;
feather.replace();
});
}
// Enhanced clear history functionality
document.getElementById('clear-history').addEventListener('click', debounce(() => {
if (confirm('Clear all chat history?')) {
document.getElementById('chat-history').innerHTML = '';
chatHistory = [];
localStorage.removeItem('chatHistory');
}
}, 200));
}); |