class MinecraftChatParser { constructor() { this.chatCategories = document.getElementById('chatCategories'); this.categoryFilter = document.getElementById('categoryFilter'); this.categorySelect = document.getElementById('categorySelect'); this.controls = document.getElementById('controls'); this.chatContainer = document.getElementById('chatContainer'); this.chatContent = document.getElementById('chatContent'); this.legend = document.getElementById('legend'); this.messageCountEl = document.getElementById('messageCount'); this.playerCountEl = document.getElementById('playerCount'); this.showTimestamps = document.getElementById('showTimestamps'); this.showJoinLeave = document.getElementById('showJoinLeave'); this.highlightRoles = document.getElementById('highlightRoles'); this.downloadFormatted = document.getElementById('downloadFormatted'); this.downloadMap = document.getElementById('downloadMap'); this.chatData = []; this.players = new Set(); this.availableChats = []; this.categories = {}; this.currentChatInfo = null; this.selectedCategory = 'all'; this.initEventListeners(); this.loadAvailableChats(); } initEventListeners() { // Control events this.showTimestamps.addEventListener('change', () => this.renderChat()); this.showJoinLeave.addEventListener('change', () => this.renderChat()); this.highlightRoles.addEventListener('change', () => this.renderChat()); this.downloadFormatted.addEventListener('click', () => this.downloadAsHTML()); this.downloadMap.addEventListener('click', () => this.downloadMapFile()); // Category filter this.categorySelect.addEventListener('change', (e) => { this.selectedCategory = e.target.value; this.renderChatCategories(); }); } async loadAvailableChats() { try { const response = await fetch('./chat-logs/chat-index.json'); const data = await response.json(); // Handle both old and new format if (Array.isArray(data)) { // Old format - convert to new format this.availableChats = data; this.categories = {}; } else { // New format with categories this.categories = data.categories || {}; this.availableChats = data.chats || []; } this.setupCategoryFilter(); this.renderChatCategories(); } catch (error) { console.error('Error loading chat index:', error); this.chatCategories.innerHTML = `
`; } } setupCategoryFilter() { if (Object.keys(this.categories).length === 0) { this.categoryFilter.style.display = 'none'; return; } this.categoryFilter.style.display = 'block'; this.categorySelect.innerHTML = ''; Object.entries(this.categories).forEach(([key, category]) => { const option = document.createElement('option'); option.value = key; option.textContent = category.name; this.categorySelect.appendChild(option); }); } renderChatCategories() { if (this.availableChats.length === 0) { this.chatCategories.innerHTML = 'No chat logs available
'; return; } // Group chats by category const chatsByCategory = {}; this.availableChats.forEach(chat => { const category = chat.category || 'uncategorized'; if (!chatsByCategory[category]) { chatsByCategory[category] = []; } chatsByCategory[category].push(chat); }); this.chatCategories.innerHTML = ''; // Render categories Object.entries(chatsByCategory).forEach(([categoryKey, chats]) => { if (this.selectedCategory !== 'all' && this.selectedCategory !== categoryKey) { return; } const categorySection = this.createCategorySection(categoryKey, chats); this.chatCategories.appendChild(categorySection); }); } createCategorySection(categoryKey, chats) { const section = document.createElement('div'); section.className = 'category-section'; const category = this.categories[categoryKey] || { name: '📁 Uncategorized', description: 'Chats without a specific category', color: '#666' }; const totalMessages = chats.reduce((sum, chat) => sum + chat.messages, 0); section.innerHTML = `${category.description}
${chat.description}
${description}