import { populateSources } from './extensions/load-extensions.js'; import { setupGlobalKeybinds } from './utils/keybinds.js'; import { getDomElements } from './utils/dom-loader.js'; import { performSearch, loadMoreResults } from './modules/search-handler.js'; import { createImageCard, populateTagModal } from './content/image-handler.js'; import { showMessage as uiShowMessage } from './modules/ui-utils.js'; import { applyLayoutToGallery } from './modules/layout-manager.js'; document.addEventListener('DOMContentLoaded', async () => { const domRefs = getDomElements(); const currentLayout = 'grid'; let currentSource = ''; let currentPage = 1; let isFetching = false; const favoriteIds = new Set(); const isBooksPage = window.location.pathname.includes('books.html'); try { if (window.api && window.api.getFavorites) { const favs = await window.api.getFavorites(); favs.forEach(f => favoriteIds.add(String(f.id))); } } catch (e) { console.error(e); } function showMessage(msg, type = 'success') { if (domRefs.messageBar) uiShowMessage(domRefs.messageBar, msg, type); } function showTagModal(tags) { if (domRefs.tagInfoContent) { populateTagModal(domRefs.tagInfoContent, tags); domRefs.tagInfoModal.classList.remove('hidden'); } } function localCreateImageCard(id, tags, img, thumb, type) { return createImageCard(id, tags, img, thumb, type, { currentLayout, showMessage, showTagModal, applyLayoutToGallery, favoritesGallery: document.getElementById('favorites-gallery'), favoriteIds }); } function updateHeader() { if (domRefs.headerContext) domRefs.headerContext.classList.add('hidden'); } const callbacks = { showMessage, applyLayoutToGallery, updateHeader, createImageCard: localCreateImageCard }; let currentChapters = []; let currentChapterPage = 1; const CHAPTERS_PER_PAGE = 10; function renderChapterPage() { const listContainer = document.getElementById('chapter-list-container'); if (!listContainer) return; listContainer.innerHTML = ''; const start = (currentChapterPage - 1) * CHAPTERS_PER_PAGE; const end = start + CHAPTERS_PER_PAGE; const slice = currentChapters.slice(start, end); if (slice.length === 0) { listContainer.innerHTML = '
Loading chapters...
Loading content...
No content found.
'; return; } const isTextMode = response.data[0].type === 'text'; if (isTextMode) { const pageData = response.data[0]; const textDiv = document.createElement('div'); textDiv.className = 'reader-text-content'; textDiv.innerHTML = pageData.content; readerContent.appendChild(textDiv); } else { response.data.forEach(page => { const img = document.createElement('img'); img.className = 'reader-page-img'; img.src = page.url; img.loading = "lazy"; readerContent.appendChild(img); }); } } catch (err) { console.error(err); showMessage('Failed to load content', 'error'); } } if (domRefs.searchModal) setupGlobalKeybinds(domRefs.searchModal); if (domRefs.tagInfoCloseButton) domRefs.tagInfoCloseButton.onclick = () => domRefs.tagInfoModal.classList.add('hidden'); if (domRefs.searchIconButton) { domRefs.searchIconButton.onclick = () => { domRefs.searchModal.classList.remove('hidden'); domRefs.searchInput?.focus(); }; domRefs.searchCloseButton.onclick = () => domRefs.searchModal.classList.add('hidden'); } if (domRefs.sourceList) { if (domRefs.contentGallery) { applyLayoutToGallery(domRefs.contentGallery, currentLayout); } const contentType = isBooksPage ? 'book-board' : 'image-board'; let initialSource = await populateSources(domRefs.sourceList, contentType); currentSource = initialSource; updateHeader(); domRefs.sourceList.addEventListener('click', (e) => { const button = e.target.closest('.source-button'); if (button) { domRefs.sourceList.querySelectorAll('.source-button').forEach(b => b.classList.remove('active')); button.classList.add('active'); currentSource = button.dataset.source; updateHeader(); currentPage = 1; // Apply books-only class when searching on books page if (isBooksPage && domRefs.contentGallery) { domRefs.contentGallery.classList.add('books-only'); } if (domRefs.searchInput?.value.trim()) performSearch(currentSource, domRefs.searchInput, currentLayout, domRefs, callbacks); else if (domRefs.searchInput) performSearch(currentSource, { value: "" }, currentLayout, domRefs, callbacks); } }); if (domRefs.contentGallery) { domRefs.contentGallery.addEventListener('click', (e) => { const card = e.target.closest('.image-entry'); if (card && isBooksPage) { if (e.target.closest('button')) return; e.preventDefault(); e.stopPropagation(); const bookId = card.dataset.id; const img = card.querySelector('img'); const title = card.dataset.title || "Unknown"; if (bookId) openBookDetails(bookId, img ? img.src : '', title, []); } }); } const scrollContainer = document.querySelector('.content-view'); if (scrollContainer) { scrollContainer.addEventListener('scroll', async () => { if (scrollContainer.scrollTop + scrollContainer.clientHeight >= scrollContainer.scrollHeight - 600) { if (isFetching) return; isFetching = true; currentPage++; if (domRefs.infiniteLoadingSpinner) domRefs.infiniteLoadingSpinner.classList.remove('hidden'); try { await loadMoreResults(currentSource, currentPage, currentLayout, domRefs, callbacks); } catch (error) { currentPage--; } finally { isFetching = false; if (domRefs.infiniteLoadingSpinner) domRefs.infiniteLoadingSpinner.classList.add('hidden'); } } }); } if (domRefs.searchButton) { domRefs.searchButton.onclick = () => { currentPage = 1; performSearch(currentSource, domRefs.searchInput, currentLayout, domRefs, callbacks); }; } } if (document.getElementById('favorites-gallery')) { const favGallery = document.getElementById('favorites-gallery'); const rawFavorites = await window.api.getFavorites(); favGallery.innerHTML = ''; if (!rawFavorites || rawFavorites.length === 0) favGallery.innerHTML = 'No favorites found.