| document.addEventListener('DOMContentLoaded', function() { |
| |
| const loadingModal = document.getElementById('loading-modal'); |
| const randomAvatarContainer = document.getElementById('random-avatar-container'); |
| const loadingProgressBar = document.getElementById('loading-progress-bar'); |
| const configList = document.getElementById('config-list'); |
| const configDisplay = document.getElementById('config-display'); |
| const welcomeMessage = document.getElementById('welcome-message'); |
| const searchInput = document.getElementById('search-input'); |
| const searchButton = document.getElementById('search-button'); |
| const resetSearchButton = document.getElementById('reset-search-button'); |
| const avatarModal = document.getElementById('avatar-modal'); |
| const modalImg = document.getElementById('modal-img'); |
| const modalCaption = document.getElementById('modal-caption'); |
| const modalClose = document.querySelector('.modal-close'); |
| const randomConfigBtn = document.getElementById('random-config-btn'); |
| const mobileRandomConfigBtn = document.getElementById('mobile-random-config-btn'); |
| |
| |
| const mobileSearchInput = document.getElementById('mobile-search-input'); |
| const mobileSearchButton = document.getElementById('mobile-search-button'); |
| const mobileResetButton = document.getElementById('mobile-reset-button'); |
| |
| |
| const avatarImages = [ |
| '/images/avatar-photos/glum-android.webp', |
| '/images/avatar-photos/confused-looking-bot.webp', |
| '/images/avatar-photos/unhappy-android-in-chair.webp', |
| '/images/avatar-photos/bot-and-laptop-speech-bubble.webp', |
| '/images/avatar-photos/sloth-detective.webp', |
| '/images/avatar-photos/tech-support-penguin.webp', |
| '/images/avatar-photos/cat-typing-on-computer.webp', |
| '/images/avatar-photos/fox-typing.webp' |
| ]; |
|
|
| |
| const loadingMessages = [ |
| "AI Bots Powering Up...", |
| "Robots Learning Human Jokes...", |
| "Digital Assistants Assembling...", |
| "Neural Networks Syncing...", |
| "AI Minions Getting Ready...", |
| "Bots Calculating Responses...", |
| "Virtual Helpers Activating...", |
| "Artificial Intelligence Loading...", |
| "Bot Army Mobilizing...", |
| "Digital Brains Thinking...", |
| "AI Assistants Waking Up...", |
| "Robot Friends Connecting..." |
| ]; |
| |
| |
| function selectRandomAvatar() { |
| const randomIndex = Math.floor(Math.random() * avatarImages.length); |
| const avatarSrc = avatarImages[randomIndex]; |
| |
| |
| const avatarImg = document.createElement('img'); |
| avatarImg.src = avatarSrc; |
| avatarImg.alt = 'Random AI Avatar'; |
| |
| |
| if (randomAvatarContainer) { |
| randomAvatarContainer.innerHTML = ''; |
| randomAvatarContainer.appendChild(avatarImg); |
| } |
| } |
|
|
| |
| function isFirstVisit() { |
| if (localStorage.getItem('hasVisitedBefore') === null) { |
| localStorage.setItem('hasVisitedBefore', 'true'); |
| return true; |
| } |
| return false; |
| } |
|
|
| |
| function setLoadingMessage() { |
| const loadingHeader = document.querySelector('.loading-modal h2'); |
| const desktopNotice = document.querySelector('.desktop-notice'); |
| |
| if (!isFirstVisit() && loadingHeader) { |
| loadingHeader.textContent = loadingMessages[Math.floor(Math.random() * loadingMessages.length)]; |
| if (desktopNotice) desktopNotice.style.display = 'none'; |
| } |
| } |
| |
| |
| function animateProgressBar() { |
| let progress = 0; |
| const progressEmoji = document.querySelector('.progress-emoji'); |
| |
| const interval = setInterval(() => { |
| progress += 1; |
| |
| if (loadingProgressBar) { |
| loadingProgressBar.style.width = `${progress}%`; |
| } |
| |
| if (progressEmoji) { |
| progressEmoji.style.left = `${progress}%`; |
| } |
| |
| if (progress >= 100) { |
| clearInterval(interval); |
| setTimeout(() => { |
| if (loadingModal) loadingModal.style.display = 'none'; |
| }, 500); |
| } |
| }, 50); |
| } |
| |
| |
| function updateConfigCount(count) { |
| const configCountElements = document.querySelectorAll('.config-count-small'); |
| if (configCountElements.length > 0) { |
| configCountElements.forEach(element => { |
| element.textContent = `(${count})`; |
| }); |
| } |
| } |
| |
| selectRandomAvatar(); |
| setLoadingMessage(); |
| animateProgressBar(); |
| |
| |
| let allConfigurations = []; |
| |
| function loadRandomConfiguration() { |
| if (allConfigurations.length === 0) { |
| showToast('No configurations available'); |
| return; |
| } |
| |
| const randomIndex = Math.floor(Math.random() * allConfigurations.length); |
| const randomConfig = allConfigurations[randomIndex]; |
| |
| loadConfiguration(randomConfig.filename); |
| |
| |
| const configLinks = document.querySelectorAll('#config-list a'); |
| configLinks.forEach(link => { |
| if (link.getAttribute('data-filename') === randomConfig.filename) { |
| link.scrollIntoView({ behavior: 'smooth', block: 'center' }); |
| } |
| }); |
| } |
| |
| fetch('configs-list.json') |
| .then(response => response.json()) |
| .then(data => { |
| if (!data || data.length === 0) { |
| configList.innerHTML = '<li>No configurations found. Please run the build script first.</li>'; |
| return; |
| } |
| |
| allConfigurations = data; |
| |
| |
| updateConfigCount(allConfigurations.length); |
| populateConfigList(allConfigurations); |
| |
| |
| if (randomConfigBtn) { |
| randomConfigBtn.addEventListener('click', function(e) { |
| e.preventDefault(); |
| loadRandomConfiguration(); |
| }); |
| } |
| |
| |
| }) |
| .catch(error => { |
| console.error('Error fetching configurations:', error); |
| configList.innerHTML = '<li>Error loading configurations. Please make sure configs-list.json exists.</li>'; |
| }); |
| |
| |
| function populateConfigList(configurations) { |
| |
| configurations.sort((a, b) => a.name.localeCompare(b.name)); |
| |
| |
| configList.innerHTML = ''; |
| |
| |
| configurations.forEach(config => { |
| const listItem = document.createElement('li'); |
| const link = document.createElement('a'); |
| link.href = '#'; |
| link.textContent = config.name; |
| link.setAttribute('data-filename', config.filename); |
| |
| link.addEventListener('click', function(e) { |
| e.preventDefault(); |
| loadConfiguration(config.filename); |
| }); |
| |
| listItem.appendChild(link); |
| configList.appendChild(listItem); |
| }); |
| } |
| |
| |
| function loadConfiguration(filename) { |
| fetch(`generated-configs/${filename}`) |
| .then(response => response.json()) |
| .then(config => { |
| displayConfiguration(config); |
| }) |
| .catch(error => { |
| console.error('Error loading configuration:', error); |
| configDisplay.innerHTML = '<p>Error loading configuration</p>'; |
| }); |
| } |
| |
| |
| function displayConfiguration(config) { |
| if (!config) { |
| configDisplay.innerHTML = '<p>Error: Configuration data is missing or invalid.</p>'; |
| welcomeMessage.style.display = 'none'; |
| configDisplay.style.display = 'block'; |
| return; |
| } |
| |
| |
| welcomeMessage.style.display = 'none'; |
| configDisplay.style.display = 'block'; |
| |
| |
| let html = ` |
| <div class="config-header"> |
| ${config.avatar ? `<img src="${config.avatar}" alt="${config.name}" class="config-avatar" onclick="openModal('${config.avatar}', '${escapeJS(config.name)}')">` : ''} |
| <div class="config-title"> |
| <h2>${config.name}</h2> |
| </div> |
| </div> |
| |
| <div class="config-section"> |
| <h3>Description</h3> |
| <p>${config.description}</p> |
| </div> |
| |
| <div class="config-section"> |
| <h3>System Prompt</h3> |
| <div class="system-prompt"> |
| <pre>${config.systemPrompt.replace(/</g, '<').replace(/>/g, '>')}</pre> |
| <button class="copy-btn" onclick="copyToClipboard('${escapeJS(config.systemPrompt)}')"> |
| <i class="fas fa-clipboard"></i> Copy |
| </button> |
| </div> |
| </div> |
| |
| <div class="action-buttons"> |
| <button class="action-btn" onclick="copyAllToClipboard('${escapeJS(config.name)}', '${escapeJS(config.description)}', '${escapeJS(config.systemPrompt)}')"> |
| <i class="fas fa-copy"></i> Copy All |
| </button> |
| <button class="action-btn" onclick="copyToClipboard('${escapeJS(config.systemPrompt)}')"> |
| <i class="fas fa-clipboard"></i> Copy System Prompt |
| </button> |
| <button class="action-btn" onclick="downloadMarkdown('${escapeJS(config.name)}', '${escapeJS(config.description)}', '${escapeJS(config.systemPrompt)}')"> |
| <i class="fas fa-download"></i> Download Markdown |
| </button> |
| </div> |
| `; |
| |
| configDisplay.innerHTML = html; |
| } |
| |
| |
| searchButton.addEventListener('click', performSearch); |
| searchInput.addEventListener('keyup', function(e) { |
| if (e.key === 'Enter') { |
| performSearch(searchInput.value); |
| } |
| }); |
| |
| |
| resetSearchButton.addEventListener('click', function() { |
| searchInput.value = ''; |
| if (mobileSearchInput) mobileSearchInput.value = ''; |
| populateConfigList(allConfigurations); |
| }); |
| |
| |
| if (mobileSearchButton) { |
| mobileSearchButton.addEventListener('click', function() { |
| performSearch(mobileSearchInput.value); |
| }); |
| } |
| |
| |
| if (mobileResetButton) { |
| mobileResetButton.addEventListener('click', function() { |
| if (mobileSearchInput) mobileSearchInput.value = ''; |
| populateConfigList(allConfigurations); |
| }); |
| } |
| |
| |
| if (mobileSearchInput) { |
| mobileSearchInput.addEventListener('keyup', function(e) { |
| if (e.key === 'Enter') { |
| performSearch(mobileSearchInput.value); |
| } |
| }); |
| } |
| |
| |
| if (mobileRandomConfigBtn) { |
| mobileRandomConfigBtn.addEventListener('click', function(e) { |
| e.preventDefault(); |
| loadRandomConfiguration(); |
| }); |
| } |
| |
| function performSearch(inputValue) { |
| const searchTerm = (inputValue || searchInput.value).toLowerCase().trim(); |
| |
| |
| searchInput.value = searchTerm; |
| if (mobileSearchInput) { |
| mobileSearchInput.value = searchTerm; |
| } |
| |
| if (searchTerm === '') { |
| populateConfigList(allConfigurations); |
| return; |
| } |
| |
| const filteredConfigs = allConfigurations.filter(config => |
| config.name.toLowerCase().includes(searchTerm) || |
| config.description.toLowerCase().includes(searchTerm) || |
| config.systemPrompt.toLowerCase().includes(searchTerm) |
| ); |
| |
| populateConfigList(filteredConfigs); |
| } |
| |
| |
| modalClose.addEventListener('click', function() { |
| avatarModal.style.display = "none"; |
| }); |
| |
| |
| window.addEventListener('click', function(event) { |
| if (event.target === avatarModal) { |
| avatarModal.style.display = "none"; |
| } |
| }); |
| }); |
|
|
| |
| function escapeJS(string) { |
| return string |
| .replace(/\\/g, '\\\\') |
| .replace(/'/g, "\\'") |
| .replace(/"/g, '\\"') |
| .replace(/\n/g, '\\n') |
| .replace(/\r/g, '\\r') |
| .replace(/\t/g, '\\t'); |
| } |
|
|
| |
| function openModal(src, name) { |
| const modal = document.getElementById('avatar-modal'); |
| const modalImg = document.getElementById('modal-img'); |
| const modalCaption = document.getElementById('modal-caption'); |
| |
| modal.style.display = "block"; |
| modalImg.src = src; |
| modalCaption.innerHTML = name; |
| } |
|
|
| |
| function copyToClipboard(text) { |
| navigator.clipboard.writeText(text) |
| .then(() => { |
| showToast('System prompt copied to clipboard!'); |
| }) |
| .catch(err => { |
| console.error('Failed to copy text: ', err); |
| |
| fallbackCopyToClipboard(text); |
| }); |
| } |
|
|
| |
| function copyAllToClipboard(name, description, systemPrompt) { |
| const text = `# ${name}\n\n${description}\n\n## System Prompt\n\n${systemPrompt}`; |
| |
| navigator.clipboard.writeText(text) |
| .then(() => { |
| showToast('All configuration details copied to clipboard!'); |
| }) |
| .catch(err => { |
| console.error('Failed to copy text: ', err); |
| |
| fallbackCopyToClipboard(text); |
| }); |
| } |
|
|
| |
| function downloadMarkdown(name, description, systemPrompt) { |
| const text = `# ${name}\n\n${description}\n\n## System Prompt\n\n${systemPrompt}`; |
| const blob = new Blob([text], { type: 'text/markdown' }); |
| const url = URL.createObjectURL(blob); |
| |
| const a = document.createElement('a'); |
| a.href = url; |
| a.download = `${name.replace(/[^a-z0-9]/gi, '-').toLowerCase()}.md`; |
| document.body.appendChild(a); |
| a.click(); |
| document.body.removeChild(a); |
| URL.revokeObjectURL(url); |
| } |
|
|
| |
| function showToast(message) { |
| |
| let toast = document.getElementById('toast'); |
| if (!toast) { |
| toast = document.createElement('div'); |
| toast.id = 'toast'; |
| document.body.appendChild(toast); |
| |
| |
| const style = document.createElement('style'); |
| style.textContent = ` |
| #toast { |
| position: fixed; |
| bottom: 30px; |
| left: 50%; |
| transform: translate(-50%, 0); |
| background-color: rgba(106, 13, 173, 0.9); |
| color: white; |
| padding: 10px 20px; |
| border-radius: 5px; |
| z-index: 1000; |
| font-family: 'Orbitron', sans-serif; |
| box-shadow: 0 4px 8px rgba(0, 0, 0, 0.3); |
| opacity: 0; |
| transition: opacity 0.3s; |
| text-align: center; |
| } |
| |
| @media (max-width: 768px) { |
| #toast { |
| bottom: 20px; /* Position at the bottom with space */ |
| } |
| } |
| |
| #toast.show { |
| opacity: 1; |
| } |
| `; |
| document.head.appendChild(style); |
| } |
| |
| |
| toast.textContent = message; |
| toast.classList.add('show'); |
| |
| |
| setTimeout(() => { |
| toast.classList.remove('show'); |
| }, 3000); |
| } |
|
|
| |
| function fallbackCopyToClipboard(text) { |
| |
| const textArea = document.createElement('textarea'); |
| textArea.value = text; |
| |
| |
| textArea.style.position = 'fixed'; |
| textArea.style.left = '-999999px'; |
| textArea.style.top = '-999999px'; |
| document.body.appendChild(textArea); |
| |
| |
| textArea.focus(); |
| textArea.select(); |
| |
| let success = false; |
| try { |
| success = document.execCommand('copy'); |
| } catch (err) { |
| console.error('Fallback: Oops, unable to copy', err); |
| } |
| |
| document.body.removeChild(textArea); |
| |
| if (success) { |
| showToast('Copied to clipboard!'); |
| } else { |
| showToast('Failed to copy text. Your browser may not support this feature.'); |
| } |
| } |
|
|
| |
| document.addEventListener('DOMContentLoaded', function() { |
| |
| const currentPath = window.location.pathname; |
| const mobileNavItems = document.querySelectorAll('.mobile-nav-item'); |
| |
| mobileNavItems.forEach(item => { |
| const itemPath = item.getAttribute('href'); |
| if (itemPath === currentPath || (currentPath === '/' && itemPath === '/')) { |
| item.classList.add('active'); |
| } else { |
| item.classList.remove('active'); |
| } |
| }); |
| |
| |
| const searchInput = document.getElementById('search-input'); |
| const mobileSearchInput = document.getElementById('mobile-search-input'); |
| |
| if (searchInput && mobileSearchInput) { |
| |
| searchInput.addEventListener('input', function() { |
| mobileSearchInput.value = this.value; |
| }); |
| |
| |
| mobileSearchInput.addEventListener('input', function() { |
| searchInput.value = this.value; |
| }); |
| } |
| }); |