/** * Requestarr Settings - Settings and history management */ export class RequestarrSettings { constructor(core) { this.core = core; this.hiddenMediaControlsInitialized = false; this.hiddenMediaItems = []; this.blacklistedTvGenres = []; this.blacklistedMovieGenres = []; this.tvGenresForBlacklist = []; this.movieGenresForBlacklist = []; this.hiddenMediaState = { mediaType: null, instanceValue: '', searchQuery: '', page: 1, pageSize: 20 }; } // ======================================== // HISTORY // ======================================== async loadHistory() { const container = document.getElementById('history-list'); if (!container) return; container.innerHTML = '
Loading history...
No request history
'; } } catch (error) { console.error('[RequestarrDiscover] Error loading history:', error); container.innerHTML = 'Failed to load history
'; } } async createHistoryItem(request) { const item = document.createElement('div'); item.className = 'history-item'; const posterUrl = request.poster_path || './static/images/no-poster.png'; const date = new Date(request.requested_at).toLocaleDateString(); item.innerHTML = `Loading hidden media...
Failed to load hidden media.
'; } } initializeHiddenMediaControls() { if (this.hiddenMediaControlsInitialized) { return; } const searchInput = document.getElementById('hidden-media-search'); if (searchInput) { searchInput.addEventListener('input', (event) => { const value = event.target.value || ''; clearTimeout(this.hiddenMediaSearchTimeout); this.hiddenMediaSearchTimeout = setTimeout(() => { this.hiddenMediaState.searchQuery = value.trim(); this.hiddenMediaState.page = 1; this.renderHiddenMediaPage(); }, 200); }); } this.hiddenMediaControlsInitialized = true; } async fetchHiddenMediaItems(mediaType) { const allItems = []; const pageSize = 200; let currentPage = 1; let totalPages = 1; const maxPages = 50; while (currentPage <= totalPages && currentPage <= maxPages) { let url = `./api/requestarr/hidden-media?page=${currentPage}&page_size=${pageSize}`; if (mediaType) { url += `&media_type=${mediaType}`; } const response = await fetch(url); if (!response.ok) { throw new Error(`Hidden media API error: ${response.status}`); } const data = await response.json(); if (data.hidden_media && data.hidden_media.length > 0) { allItems.push(...data.hidden_media); } totalPages = data.total_pages || 1; currentPage += 1; } return allItems; } async fetchGlobalBlacklistItems(mediaType) { try { const resp = await fetch('./api/requestarr/requests/global-blacklist/ids'); if (!resp.ok) return []; const data = await resp.json(); let items = data.items || []; if (mediaType) { items = items.filter(i => i.media_type === mediaType); } return items.map(i => ({ tmdb_id: i.tmdb_id, media_type: i.media_type, title: i.title || '', poster_path: i.poster_path || '' })); } catch (err) { console.error('[RequestarrSettings] Error fetching global blacklist:', err); return []; } } getFilteredHiddenMedia() { const query = (this.hiddenMediaState.searchQuery || '').toLowerCase(); let filtered = this.hiddenMediaItems.slice(); if (query) { filtered = filtered.filter(item => (item.title || '').toLowerCase().includes(query)); } filtered.sort((a, b) => { const titleA = (a.title || '').toLowerCase(); const titleB = (b.title || '').toLowerCase(); return titleA.localeCompare(titleB); }); return filtered; } renderHiddenMediaPage() { const container = document.getElementById('hidden-media-grid'); const paginationContainer = document.getElementById('hidden-media-pagination'); if (!container || !paginationContainer) { return; } const filtered = this.getFilteredHiddenMedia(); const pageSize = this.hiddenMediaState.pageSize; const totalPages = Math.max(1, Math.ceil(filtered.length / pageSize)); if (this.hiddenMediaState.page > totalPages) { this.hiddenMediaState.page = 1; } const startIndex = (this.hiddenMediaState.page - 1) * pageSize; const pageItems = filtered.slice(startIndex, startIndex + pageSize); if (pageItems.length > 0) { container.style.display = 'grid'; container.style.alignItems = ''; container.style.justifyContent = ''; container.innerHTML = ''; pageItems.forEach(item => { container.appendChild(this.createHiddenMediaCard(item)); }); if (totalPages > 1) { paginationContainer.style.display = 'flex'; document.getElementById('hidden-page-info').textContent = `Page ${this.hiddenMediaState.page} of ${totalPages}`; document.getElementById('hidden-prev-page').disabled = this.hiddenMediaState.page === 1; document.getElementById('hidden-next-page').disabled = this.hiddenMediaState.page === totalPages; } else { paginationContainer.style.display = 'none'; } } else { container.style.display = 'flex'; container.style.alignItems = 'center'; container.style.justifyContent = 'center'; container.innerHTML = `No Blacklisted Media
Items you blacklist will appear here. Blacklisted media is hidden across all instances.