From 732591cdbc1b2580eec97bf3146d4a19c696018a Mon Sep 17 00:00:00 2001 From: HighImKevin Date: Thu, 13 Nov 2025 21:20:32 -0500 Subject: [PATCH] New feature: Watchlist Export/Import (closes #5) --- README.md | 22 +- injector.js | 2 +- pages/images/watchlist-export.png | Bin 0 -> 30956 bytes pages/images/watchlist-import.png | Bin 0 -> 64994 bytes scripts/watchlist.css | 57 +++ scripts/watchlist.js | 803 +++++++++++++++++++++++++++++- 6 files changed, 879 insertions(+), 5 deletions(-) create mode 100644 pages/images/watchlist-export.png create mode 100644 pages/images/watchlist-import.png diff --git a/README.md b/README.md index 5eb75cf..944d630 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ I think it's also worth mentioning that before the 1.0 release, you can expect t - [Feature Requests Completed](#-feature-requests-completed) - [Feature Requests Planned](#-feature-requests-planned) - [Core Features](#-core-features) - - [Watchlist Page](#watchlist-page) + - [Watchlist](#watchlist) - [Enhanced Home Screen](#enhanced-home-screen) - [Enhanced Search](#enhanced-search) - [UI Enhancements](#-ui-enhancements) @@ -62,7 +62,7 @@ I think it's also worth mentioning that before the 1.0 release, you can expect t 0a. **Install Prerequisites listed above** 0b. **If you are using JellyfinEnhanced, you MUST disable the "Watchlist" feature from the plugin settings** 1. **Add a new script to your JS Injector Plugin** -2. **Copy this entire contents of kefinTweaks.js into the new script** +2. **Copy the entire contents of kefinTweaks.js into the new script** **Optionally update the "scriptRoot" in the KefinTweaks script if you wish to customize and host these scripts yourself.** @@ -136,7 +136,7 @@ The features in KefinTweaks which use local data caching are listed below, along ### Core Features -#### **Watchlist Page** +#### **Watchlist** - **Watchlist**: Tired of forgetting everything you wanted to watch? Add movies, series, seasons, and episodes to your Watchlist! @@ -168,6 +168,21 @@ A summary of your watched items by the numbers. See how many movies, shows or ep statistics +- **Export/Import**: +Export your Watchlist to JSON which can later be imported using the Watchlist Import feature. You can use this feature to make bulk changes to your Watchlist if you need to. + + + + + + + + + + +
Watchlist ExportWatchlist Import
+
+ - **Auto-Remove**: Automatically removes watched items from your watchlist when playback completes. @@ -423,6 +438,7 @@ Allow users to also customize various configuration options through the UI
### Version History +- **v0.2.4**: New Feature: Watchlist Export/Import - **v0.2.3**: New Feature: Collection Sorting, general fixes - **v0.2.2**: Add support for skin server versions, fixes for HeaderTabs - **v0.2.1**: Caching improvements for Watchlist and Top People, Mobile UI fixes and Flatten TV Shows improvements diff --git a/injector.js b/injector.js index 96dbe8c..a96b9a2 100644 --- a/injector.js +++ b/injector.js @@ -6,7 +6,7 @@ 'use strict'; console.log('[KefinTweaks Injector] Initializing...'); - const versionNumber = "0.2.3"; + const versionNumber = "0.2.4"; // Configuration: Start with defaults, then merge user config // This allows new scripts to work out of the box without requiring config updates diff --git a/pages/images/watchlist-export.png b/pages/images/watchlist-export.png new file mode 100644 index 0000000000000000000000000000000000000000..cb77d35c21e0e307375ff502e74577642636eea7 GIT binary patch literal 30956 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 literal 0 HcmV?d00001 diff --git a/pages/images/watchlist-import.png b/pages/images/watchlist-import.png new file mode 100644 index 0000000000000000000000000000000000000000..71536faf954b61b2a4c1475308abc7660eee9ece GIT binary patch literal 64994 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 L+}wbycP;K;ID3!b literal 0 HcmV?d00001 diff --git a/scripts/watchlist.css b/scripts/watchlist.css index b19ef7a..cb6fa19 100644 --- a/scripts/watchlist.css +++ b/scripts/watchlist.css @@ -1866,6 +1866,58 @@ div[data-tab="watchlist"] .loading-message { display: none; } +/* Import/Export Modal Styles */ +.import-export-modal-content { + min-width: 500px; + max-width: 800px; +} + +.import-export-tabs { + display: flex; + gap: 8px; + margin-bottom: 20px; + border-bottom: 1px solid rgba(255, 255, 255, 0.1); +} + +.import-export-tab { + flex: 1; + padding: 12px; + background: transparent; + border: none; + border-bottom: 2px solid transparent; + color: rgba(255, 255, 255, 0.7); + cursor: pointer; + font-size: 14px; + font-weight: 500; + transition: all 0.2s ease; +} + +.import-export-tab:hover { + color: rgba(255, 255, 255, 0.9); + background: rgba(255, 255, 255, 0.05); +} + +.import-export-tab.active { + color: #fff; + border-bottom-color: #00a4dc; +} + +.import-export-tab-content { + min-height: 400px; +} + +/* Responsive Design for Import/Export Modal */ +@media (max-width: 768px) { + .import-export-modal-content { + min-width: calc(100vw - 40px); + max-width: calc(100vw - 40px); + } + + .import-export-tab-content { + min-height: 300px; + } +} + /* List View Styling */ [data-layout='List'] .cardScalable { display: none; @@ -1901,3 +1953,8 @@ div[data-tab="watchlist"] .loading-message { padding-top: .24em; } +.import-export-tab-content { + display: flex; + flex-direction: column; + gap: 10px; +} \ No newline at end of file diff --git a/scripts/watchlist.js b/scripts/watchlist.js index c4e340a..edc2cd9 100644 --- a/scripts/watchlist.js +++ b/scripts/watchlist.js @@ -145,6 +145,8 @@ In the Custom Tabs plugin, add a new tab with the following HTML content: // Watchlist tab refresh button const watchlistHeaderRight = watchlistSection.querySelector('.watchlist-header-right'); if (watchlistHeaderRight) { + const importExportBtn = createImportExportButton(); + watchlistHeaderRight.appendChild(importExportBtn); const refreshBtn = createRefreshButton('watchlist', 'Watchlist'); watchlistHeaderRight.appendChild(refreshBtn); } @@ -215,6 +217,20 @@ In the Custom Tabs plugin, add a new tab with the following HTML content: return refreshBtn; } + // Create import/export button element + function createImportExportButton() { + const btn = document.createElement('button'); + btn.className = 'layout-toggle-btn'; + btn.innerHTML = ''; + btn.title = 'Import/Export Watchlist'; + + btn.onclick = () => { + showImportExportModal(); + }; + + return btn; + } + // Create sort button element function createSortButton() { const sortBtn = document.createElement('button'); @@ -3252,6 +3268,791 @@ In the Custom Tabs plugin, add a new tab with the following HTML content: LOG('Watchlist HTML structure rendered successfully'); } + /************ Import/Export Functions ************/ + + // Show import/export modal + function showImportExportModal() { + const modalContent = document.createElement('div'); + modalContent.className = 'import-export-modal-content'; + modalContent.style.minWidth = '500px'; + modalContent.style.maxWidth = '800px'; + + // Create tab buttons + const tabContainer = document.createElement('div'); + tabContainer.className = 'import-export-tabs'; + tabContainer.style.display = 'flex'; + tabContainer.style.gap = '8px'; + tabContainer.style.marginBottom = '20px'; + tabContainer.style.borderBottom = '1px solid rgba(255, 255, 255, 0.1)'; + + const exportTabBtn = document.createElement('button'); + exportTabBtn.className = 'import-export-tab active'; + exportTabBtn.textContent = 'Export'; + exportTabBtn.style.cssText = 'flex: 1; padding: 12px; background: transparent; border: none; border-bottom: 2px solid #00a4dc; color: rgba(255, 255, 255, 0.7); cursor: pointer; font-size: 14px; font-weight: 500;'; + + const importTabBtn = document.createElement('button'); + importTabBtn.className = 'import-export-tab'; + importTabBtn.textContent = 'Import'; + importTabBtn.style.cssText = 'flex: 1; padding: 12px; background: transparent; border: none; border-bottom: 2px solid transparent; color: rgba(255, 255, 255, 0.7); cursor: pointer; font-size: 14px; font-weight: 500;'; + + // Tab content container + const tabContent = document.createElement('div'); + tabContent.className = 'import-export-tab-content'; + tabContent.style.minHeight = '400px'; + + // Active tab state + let activeTab = 'export'; + + // Store exported data to preserve across tab switches + let savedExportData = ''; + + // Tab switching + const switchTab = (tab) => { + // Save export data before clearing + if (activeTab === 'export') { + const exportTextarea = tabContent.querySelector('#export-textarea'); + if (exportTextarea) { + savedExportData = exportTextarea.value; + } + } + + activeTab = tab; + exportTabBtn.classList.toggle('active', tab === 'export'); + importTabBtn.classList.toggle('active', tab === 'import'); + exportTabBtn.style.borderBottomColor = tab === 'export' ? '#00a4dc' : 'transparent'; + exportTabBtn.style.color = tab === 'export' ? '#fff' : 'rgba(255, 255, 255, 0.7)'; + importTabBtn.style.borderBottomColor = tab === 'import' ? '#00a4dc' : 'transparent'; + importTabBtn.style.color = tab === 'import' ? '#fff' : 'rgba(255, 255, 255, 0.7)'; + + tabContent.innerHTML = ''; + if (tab === 'export') { + renderExportTab(tabContent, savedExportData, (newData) => { + savedExportData = newData; + }); + } else { + renderImportTab(tabContent); + } + }; + + exportTabBtn.onclick = () => switchTab('export'); + importTabBtn.onclick = () => switchTab('import'); + + tabContainer.appendChild(exportTabBtn); + tabContainer.appendChild(importTabBtn); + modalContent.appendChild(tabContainer); + modalContent.appendChild(tabContent); + + // Render default tab (export) + renderExportTab(tabContent, savedExportData, (newData) => { + savedExportData = newData; + }); + + // Create modal + const modal = window.ModalSystem.create({ + id: 'import-export-modal', + content: modalContent, + closeOnBackdrop: true, + closeOnEscape: true + }); + } + + // Render export tab + function renderExportTab(container, savedData = '', updateSavedData = null) { + container.innerHTML = ''; + + const description = document.createElement('p'); + description.style.cssText = 'color: rgba(255, 255, 255, 0.7); margin-bottom: 20px; font-size: 14px; line-height: 1.5;'; + description.textContent = 'Export your watchlist to a JSON file. The export includes item names and provider IDs (IMDb, TMDB, TVDB).'; + container.appendChild(description); + + const exportBtn = document.createElement('button'); + exportBtn.className = 'emby-button emby-button-raised button-submit'; + exportBtn.textContent = 'Export Watchlist'; + exportBtn.style.cssText = 'margin-bottom: 20px;'; + exportBtn.style.alignSelf = 'flex-start'; + + const textarea = document.createElement('textarea'); + textarea.id = 'export-textarea'; + textarea.readOnly = true; + textarea.style.cssText = 'width: 100%; min-height: 300px; padding: 12px; background: rgba(0, 0, 0, 0.3); border: 1px solid rgba(255, 255, 255, 0.2); border-radius: 4px; color: #fff; font-family: monospace; font-size: 12px; resize: vertical; box-sizing: border-box;'; + textarea.placeholder = 'Exported watchlist data will appear here...'; + // Preserve saved data if switching tabs + if (savedData) { + textarea.value = savedData; + } + container.appendChild(exportBtn); + container.appendChild(textarea); + + const buttonContainer = document.createElement('div'); + buttonContainer.style.cssText = 'display: flex; gap: 10px; margin-top: 10px;'; + + const copyBtn = document.createElement('button'); + copyBtn.className = 'emby-button'; + copyBtn.textContent = 'Copy to Clipboard'; + copyBtn.style.cssText = 'padding: 8px 16px; background: rgba(255, 255, 255, 0.1); color: white; border: 1px solid rgba(255, 255, 255, 0.2); border-radius: 4px; cursor: pointer; font-size: 14px;'; + // Enable copy button if there's saved content + copyBtn.disabled = !savedData; + + copyBtn.onclick = async () => { + try { + await navigator.clipboard.writeText(textarea.value); + copyBtn.textContent = 'Copied!'; + setTimeout(() => { + copyBtn.textContent = 'Copy to Clipboard'; + }, 2000); + } catch (err) { + ERR('Failed to copy to clipboard:', err); + alert('Failed to copy to clipboard. Please copy manually.'); + } + }; + + buttonContainer.appendChild(copyBtn); + container.appendChild(buttonContainer); + + exportBtn.onclick = async () => { + exportBtn.disabled = true; + exportBtn.textContent = 'Exporting...'; + textarea.value = ''; + + try { + const exportData = await exportWatchlistData(); + const jsonString = JSON.stringify(exportData, null, 2); + textarea.value = jsonString; + // Update saved data so it persists across tab switches + if (updateSavedData) { + updateSavedData(jsonString); + } + copyBtn.disabled = false; + exportBtn.disabled = false; + exportBtn.textContent = 'Export Watchlist'; + } catch (err) { + ERR('Export failed:', err); + textarea.value = `Error exporting watchlist: ${err.message}`; + // Clear saved data on error + if (updateSavedData) { + updateSavedData(''); + } + exportBtn.disabled = false; + exportBtn.textContent = 'Export Watchlist'; + } + }; + } + + // Render import tab + function renderImportTab(container) { + container.innerHTML = ''; + + const description = document.createElement('p'); + description.style.cssText = 'color: rgba(255, 255, 255, 0.7); margin-bottom: 20px; font-size: 14px; line-height: 1.5;'; + description.textContent = 'Paste your watchlist JSON data below. Each item must have at least one provider ID (IMDb, TMDB, or TVDB).'; + container.appendChild(description); + + const textarea = document.createElement('textarea'); + textarea.id = 'import-textarea'; + textarea.style.cssText = 'width: 100%; min-height: 200px; padding: 12px; background: rgba(0, 0, 0, 0.3); border: 1px solid rgba(255, 255, 255, 0.2); border-radius: 4px; color: #fff; font-family: monospace; font-size: 12px; resize: vertical; box-sizing: border-box; margin-bottom: 10px;'; + textarea.placeholder = 'Paste your watchlist JSON data here...'; + container.appendChild(textarea); + + const validationMsg = document.createElement('div'); + validationMsg.id = 'import-validation'; + validationMsg.style.cssText = 'margin-bottom: 10px; padding: 10px; border-radius: 4px; font-size: 13px; display: none;'; + container.appendChild(validationMsg); + + const previewContainer = document.createElement('div'); + previewContainer.id = 'import-preview'; + previewContainer.style.cssText = 'margin-bottom: 10px; max-height: 200px; overflow-y: auto; display: none;'; + container.appendChild(previewContainer); + + const progressContainer = document.createElement('div'); + progressContainer.id = 'import-progress'; + progressContainer.style.cssText = 'margin-bottom: 10px; display: none;'; + container.appendChild(progressContainer); + + const summaryContainer = document.createElement('div'); + summaryContainer.id = 'import-summary'; + summaryContainer.style.cssText = 'margin-bottom: 10px; padding: 10px; border-radius: 4px; display: none;'; + container.appendChild(summaryContainer); + + const buttonContainer = document.createElement('div'); + buttonContainer.style.cssText = 'display: flex; gap: 10px; margin-top: 10px;'; + + const validateBtn = document.createElement('button'); + validateBtn.className = 'emby-button'; + validateBtn.textContent = 'Validate & Preview'; + validateBtn.style.cssText = 'padding: 8px 16px; background: rgba(255, 255, 255, 0.1); color: white; border: 1px solid rgba(255, 255, 255, 0.2); border-radius: 4px; cursor: pointer; font-size: 14px;'; + + const importBtn = document.createElement('button'); + importBtn.className = 'emby-button emby-button-raised button-submit'; + importBtn.textContent = 'Import Watchlist'; + importBtn.disabled = true; + importBtn.style.display = 'none'; // Hide until validated + + const clearBtn = document.createElement('button'); + clearBtn.className = 'emby-button'; + clearBtn.textContent = 'Clear Watchlist'; + clearBtn.style.cssText = 'padding: 8px 16px; background: rgba(255, 0, 0, 0.2); color: #ff6b6b; border: 1px solid rgba(255, 0, 0, 0.3); border-radius: 4px; cursor: pointer; font-size: 14px; margin-left: auto;'; + + buttonContainer.appendChild(validateBtn); + buttonContainer.appendChild(importBtn); + buttonContainer.appendChild(clearBtn); + container.appendChild(buttonContainer); + + let validatedData = null; + + validateBtn.onclick = () => { + const jsonText = textarea.value.trim(); + if (!jsonText) { + showValidationMessage(validationMsg, 'Please paste JSON data first.', 'error'); + return; + } + + // Hide progress container when validating + progressContainer.style.display = 'none'; + summaryContainer.style.display = 'none'; + + try { + const data = JSON.parse(jsonText); + const validation = validateImportData(data); + + if (validation.valid) { + validatedData = data; + showValidationMessage(validationMsg, validation.message, 'success'); + showPreview(previewContainer, data); + importBtn.disabled = false; + importBtn.style.display = ''; // Show button when validated + } else { + validatedData = null; + showValidationMessage(validationMsg, validation.message, 'error'); + previewContainer.style.display = 'none'; + importBtn.disabled = true; + importBtn.style.display = 'none'; // Hide button on validation failure + } + } catch (err) { + validatedData = null; + showValidationMessage(validationMsg, `Invalid JSON: ${err.message}`, 'error'); + previewContainer.style.display = 'none'; + importBtn.disabled = true; + importBtn.style.display = 'none'; // Hide button on parse error + } + }; + + importBtn.onclick = async () => { + if (!validatedData) { + showValidationMessage(validationMsg, 'Please validate the data first.', 'error'); + return; + } + + importBtn.disabled = true; + validateBtn.disabled = true; + clearBtn.disabled = true; + summaryContainer.style.display = 'none'; + + // Show progress container immediately at 0/X items + progressContainer.style.display = 'block'; + showImportProgress(progressContainer, 0, validatedData.length, 'Starting import...'); + + try { + const results = await importWatchlistData(validatedData, progressContainer); + showImportSummary(summaryContainer, results); + summaryContainer.style.display = 'block'; + + // Refresh watchlist + await initWatchlistTab(); + renderWatchlistContent(); + } catch (err) { + ERR('Import failed:', err); + showValidationMessage(validationMsg, `Import failed: ${err.message}`, 'error'); + } finally { + importBtn.disabled = false; + validateBtn.disabled = false; + clearBtn.disabled = false; + } + }; + + clearBtn.onclick = async () => { + if (confirm('Are you sure you want to clear your entire watchlist? This action cannot be undone.')) { + if (confirm('This will remove ALL items from your watchlist. Are you absolutely sure?')) { + clearBtn.disabled = true; + clearBtn.textContent = 'Clearing...'; + try { + await clearWatchlist(); + // Close modal after clearing + window.ModalSystem.close('import-export-modal'); + } catch (err) { + ERR('Failed to clear watchlist:', err); + alert('Failed to clear watchlist. Please try again.'); + } finally { + clearBtn.disabled = false; + clearBtn.textContent = 'Clear Watchlist'; + } + } + } + }; + } + + // Show validation message + function showValidationMessage(container, message, type) { + container.style.display = 'block'; + container.textContent = message; + container.style.background = type === 'success' ? 'rgba(76, 175, 80, 0.2)' : 'rgba(255, 0, 0, 0.2)'; + container.style.border = type === 'success' ? '1px solid rgba(76, 175, 80, 0.4)' : '1px solid rgba(255, 0, 0, 0.4)'; + container.style.color = type === 'success' ? '#4caf50' : '#ff6b6b'; + } + + // Show preview + function showPreview(container, data) { + container.innerHTML = ''; + container.style.display = 'block'; + + const previewTitle = document.createElement('div'); + previewTitle.style.cssText = 'font-weight: 600; margin-bottom: 8px; color: #fff;'; + previewTitle.textContent = `Preview: ${data.length} item(s) to import`; + container.appendChild(previewTitle); + + const previewList = document.createElement('div'); + previewList.style.cssText = 'max-height: 150px; overflow-y: auto;'; + + data.slice(0, 10).forEach((item, index) => { + const itemDiv = document.createElement('div'); + itemDiv.style.cssText = 'padding: 6px; margin-bottom: 4px; background: rgba(255, 255, 255, 0.05); border-radius: 4px; font-size: 12px; color: rgba(255, 255, 255, 0.8);'; + const name = item.Name || item.name || 'Unknown'; + const providers = []; + if (item.Imdb || item.imdb) providers.push('IMDb'); + if (item.Tmdb || item.tmdb) providers.push('TMDB'); + if (item.Tvdb || item.tvdb) providers.push('TVDB'); + itemDiv.textContent = `${index + 1}. ${name} (${providers.join(', ')})`; + previewList.appendChild(itemDiv); + }); + + if (data.length > 10) { + const moreDiv = document.createElement('div'); + moreDiv.style.cssText = 'padding: 6px; font-size: 12px; color: rgba(255, 255, 255, 0.6); font-style: italic;'; + moreDiv.textContent = `... and ${data.length - 10} more item(s)`; + previewList.appendChild(moreDiv); + } + + container.appendChild(previewList); + } + + // Show import progress + function showImportProgress(container, current, total, itemName) { + container.innerHTML = ` +
+ Importing: ${current} / ${total} +
+
+
+
+
+ ${itemName || ''} +
+ `; + } + + // Show import summary + function showImportSummary(container, results) { + container.innerHTML = ''; + container.style.display = 'block'; + container.style.background = 'rgba(255, 255, 255, 0.05)'; + container.style.border = '1px solid rgba(255, 255, 255, 0.1)'; + container.style.padding = '12px'; + container.style.borderRadius = '4px'; + + const summaryTitle = document.createElement('div'); + summaryTitle.style.cssText = 'font-weight: 600; margin-bottom: 8px; color: #fff; font-size: 14px;'; + summaryTitle.textContent = 'Import Summary'; + container.appendChild(summaryTitle); + + const summaryList = document.createElement('div'); + summaryList.style.cssText = 'display: flex; flex-direction: column; gap: 4px; font-size: 13px;'; + + const successDiv = document.createElement('div'); + successDiv.style.color = '#4caf50'; + successDiv.textContent = `✓ Successfully imported: ${results.imported} item(s)`; + summaryList.appendChild(successDiv); + + if (results.skipped > 0) { + const skippedDiv = document.createElement('div'); + skippedDiv.style.color = 'rgba(255, 255, 255, 0.7)'; + skippedDiv.textContent = `⊘ Already in watchlist: ${results.skipped} item(s)`; + summaryList.appendChild(skippedDiv); + } + + if (results.notFound > 0) { + const notFoundDiv = document.createElement('div'); + notFoundDiv.style.color = '#ff6b6b'; + notFoundDiv.textContent = `✗ Not found in library: ${results.notFound} item(s)`; + summaryList.appendChild(notFoundDiv); + } + + if (results.errors > 0) { + const errorsDiv = document.createElement('div'); + errorsDiv.style.color = '#ff6b6b'; + errorsDiv.textContent = `✗ Errors: ${results.errors} item(s)`; + summaryList.appendChild(errorsDiv); + } + + container.appendChild(summaryList); + } + + // Export watchlist data from server + async function exportWatchlistData() { + const apiClient = window.ApiClient; + const userId = apiClient.getCurrentUserId(); + const serverUrl = apiClient.serverAddress(); + const token = apiClient.accessToken(); + + const exportData = []; + + // Fetch all watchlist items from server (not cache) + const types = [ + { type: 'Movie', section: 'movies' }, + { type: 'Series', section: 'series' }, + { type: 'Season', section: 'seasons' }, + { type: 'Episode', section: 'episodes' } + ]; + + for (const { type, section } of types) { + try { + // Fetch from server with Fields to get SeriesName for episodes/seasons + const url = `${serverUrl}/Items?Filters=Likes&IncludeItemTypes=${type}&UserId=${userId}&Recursive=true&Fields=ProviderIds,SeriesName,ParentId&ImageTypeLimit=1&EnableImageTypes=Primary,Backdrop,Thumb`; + const res = await fetch(url, { headers: { "Authorization": `MediaBrowser Token=\"${token}\"` } }); + const data = await res.json(); + const items = data.Items || []; + + for (const item of items) { + const exportItem = { + status: true, + Name: item.Name, + Type: type // Add Type field for efficient import + }; + + // Add provider IDs (only if they exist) + if (item.ProviderIds) { + if (item.ProviderIds.Imdb) exportItem.Imdb = item.ProviderIds.Imdb; + if (item.ProviderIds.Tmdb) exportItem.Tmdb = item.ProviderIds.Tmdb; + if (item.ProviderIds.Tvdb) exportItem.Tvdb = item.ProviderIds.Tvdb; + } + + // For episodes, add SeriesName and SeasonName + if (type === 'Episode') { + if (item.SeriesName) { + exportItem.SeriesName = item.SeriesName; + } + // Get SeasonName from parent season + if (item.ParentId) { + try { + const seasonUrl = `${serverUrl}/Items/${item.ParentId}?UserId=${userId}&Fields=Name`; + const seasonRes = await fetch(seasonUrl, { headers: { "Authorization": `MediaBrowser Token=\"${token}\"` } }); + const seasonData = await seasonRes.json(); + if (seasonData.Name) { + exportItem.SeasonName = seasonData.Name; + } + } catch (err) { + WARN('Failed to fetch season name for episode:', err); + } + } + } + + // For seasons, add SeriesName + if (type === 'Season') { + if (item.SeriesName) { + exportItem.SeriesName = item.SeriesName; + } + } + + // Only add if at least one provider ID exists + if (exportItem.Imdb || exportItem.Tmdb || exportItem.Tvdb) { + exportData.push(exportItem); + } + } + } catch (err) { + ERR(`Failed to fetch ${type} items:`, err); + } + } + + return exportData; + } + + // Validate import data + function validateImportData(data) { + if (!Array.isArray(data)) { + return { valid: false, message: 'Data must be an array of items.' }; + } + + if (data.length === 0) { + return { valid: false, message: 'No items to import.' }; + } + + const errors = []; + const providerIdMap = new Map(); // Track provider IDs for duplicate detection + + for (let i = 0; i < data.length; i++) { + const item = data[i]; + const itemNum = i + 1; + + // Check if item is an object + if (typeof item !== 'object' || item === null) { + errors.push(`Item ${itemNum}: Must be an object.`); + continue; + } + + // Check status field + if (item.status !== undefined && typeof item.status !== 'boolean') { + errors.push(`Item ${itemNum}: 'status' must be a boolean.`); + } + + // Check Type field (required) + const itemType = item.Type || item.type; + if (!itemType) { + errors.push(`Item ${itemNum}: 'Type' field is required (Movie, Series, Season, or Episode).`); + continue; + } + if (!['Movie', 'Series', 'Season', 'Episode'].includes(itemType)) { + errors.push(`Item ${itemNum}: 'Type' must be one of: Movie, Series, Season, Episode.`); + continue; + } + + // Check for at least one provider ID + const imdb = item.Imdb || item.imdb; + const tmdb = item.Tmdb || item.tmdb; + const tvdb = item.Tvdb || item.tvdb; + + if (!imdb && !tmdb && !tvdb) { + errors.push(`Item ${itemNum}: Must have at least one provider ID (Imdb, Tmdb, or Tvdb).`); + continue; + } + + // Check for duplicate provider IDs (include Type in key to allow same ID for different types) + const providerKeys = []; + if (imdb) providerKeys.push(`Imdb:${imdb}:${itemType}`); + if (tmdb) providerKeys.push(`Tmdb:${tmdb}:${itemType}`); + if (tvdb) providerKeys.push(`Tvdb:${tvdb}:${itemType}`); + + for (const key of providerKeys) { + if (providerIdMap.has(key)) { + const existingItem = providerIdMap.get(key); + errors.push(`Item ${itemNum}: Duplicate provider ID '${key}' found (also in item ${existingItem}).`); + } else { + providerIdMap.set(key, itemNum); + } + } + } + + if (errors.length > 0) { + return { valid: false, message: `Validation failed:\n${errors.slice(0, 10).join('\n')}${errors.length > 10 ? `\n... and ${errors.length - 10} more error(s).` : ''}` }; + } + + return { valid: true, message: `Validation successful: ${data.length} item(s) ready to import.` }; + } + + // Import watchlist data + async function importWatchlistData(data, progressContainer) { + const apiClient = window.ApiClient; + const userId = apiClient.getCurrentUserId(); + const serverUrl = apiClient.serverAddress(); + const token = apiClient.accessToken(); + + const results = { + imported: 0, + skipped: 0, + notFound: 0, + errors: 0 + }; + + // Analyze import data to determine which types are used + const usedTypes = new Set(); + for (const item of data) { + const itemType = item.Type || item.type; + if (itemType) usedTypes.add(itemType); + } + + // Build query parameters + const includeTypes = Array.from(usedTypes).join(','); + const queryParams = new URLSearchParams({ + UserId: userId, + Recursive: 'true', + IncludeItemTypes: includeTypes, + Fields: 'ProviderIds,Type' + }); + + // Fetch all matching items in bulk + let allLibraryItems = []; + try { + const url = `${serverUrl}/Items?${queryParams.toString()}`; + const res = await fetch(url, { headers: { "Authorization": `MediaBrowser Token=\"${token}\"` } }); + const libraryData = await res.json(); + allLibraryItems = libraryData.Items || []; + LOG(`Fetched ${allLibraryItems.length} items from library matching import criteria`); + } catch (err) { + ERR('Failed to fetch library items:', err); + throw new Error('Failed to fetch library items. Please try again.'); + } + + // Create a lookup map: providerId -> item + const libraryMap = new Map(); + for (const item of allLibraryItems) { + if (item.ProviderIds) { + if (item.ProviderIds.Imdb) { + const key = `Imdb:${item.ProviderIds.Imdb}:${item.Type}`; + libraryMap.set(key, item); + } + if (item.ProviderIds.Tmdb) { + const key = `Tmdb:${item.ProviderIds.Tmdb}:${item.Type}`; + libraryMap.set(key, item); + } + if (item.ProviderIds.Tvdb) { + const key = `Tvdb:${item.ProviderIds.Tvdb}:${item.Type}`; + libraryMap.set(key, item); + } + } + } + + // Get all current watchlist items to check for duplicates + const currentWatchlist = new Set(); + const watchlistTypes = ['Movie', 'Series', 'Season', 'Episode']; + for (const type of watchlistTypes) { + try { + const url = `${serverUrl}/Items?Filters=Likes&IncludeItemTypes=${type}&UserId=${userId}&Recursive=true&Fields=ProviderIds`; + const res = await fetch(url, { headers: { "Authorization": `MediaBrowser Token=\"${token}\"` } }); + const watchlistData = await res.json(); + const items = watchlistData.Items || []; + for (const item of items) { + if (item.ProviderIds) { + if (item.ProviderIds.Imdb) currentWatchlist.add(`Imdb:${item.ProviderIds.Imdb}:${type}`); + if (item.ProviderIds.Tmdb) currentWatchlist.add(`Tmdb:${item.ProviderIds.Tmdb}:${type}`); + if (item.ProviderIds.Tvdb) currentWatchlist.add(`Tvdb:${item.ProviderIds.Tvdb}:${type}`); + } + } + } catch (err) { + WARN(`Failed to fetch current watchlist for ${type}:`, err); + } + } + + // Process each import item + for (let i = 0; i < data.length; i++) { + const importItem = data[i]; + const itemName = importItem.Name || importItem.name || `Item ${i + 1}`; + + // Update progress before processing item + showImportProgress(progressContainer, i + 1, data.length, itemName); + + // Allow UI to update before processing + await new Promise(resolve => requestAnimationFrame(resolve)); + + try { + // Get provider IDs and type + const imdb = importItem.Imdb || importItem.imdb; + const tmdb = importItem.Tmdb || importItem.tmdb; + const tvdb = importItem.Tvdb || importItem.tvdb; + const itemType = importItem.Type || importItem.type; + + // Find matching item in library using provider IDs and type + let foundItem = null; + const searchKeys = []; + if (imdb) searchKeys.push(`Imdb:${imdb}:${itemType}`); + if (tmdb) searchKeys.push(`Tmdb:${tmdb}:${itemType}`); + if (tvdb) searchKeys.push(`Tvdb:${tvdb}:${itemType}`); + + for (const key of searchKeys) { + if (libraryMap.has(key)) { + foundItem = libraryMap.get(key); + break; // Use first match + } + } + + if (!foundItem) { + results.notFound++; + // Update progress after processing + await new Promise(resolve => requestAnimationFrame(resolve)); + continue; + } + + // Check if already in watchlist + let alreadyInWatchlist = false; + for (const key of searchKeys) { + if (currentWatchlist.has(key)) { + alreadyInWatchlist = true; + break; + } + } + + if (alreadyInWatchlist) { + results.skipped++; + // Update progress after processing + await new Promise(resolve => requestAnimationFrame(resolve)); + continue; + } + + // Add to watchlist + await apiClient.updateUserItemRating(userId, foundItem.Id, 'true'); + results.imported++; + + // Update current watchlist set + if (foundItem.ProviderIds) { + if (foundItem.ProviderIds.Imdb) currentWatchlist.add(`Imdb:${foundItem.ProviderIds.Imdb}:${foundItem.Type}`); + if (foundItem.ProviderIds.Tmdb) currentWatchlist.add(`Tmdb:${foundItem.ProviderIds.Tmdb}:${foundItem.Type}`); + if (foundItem.ProviderIds.Tvdb) currentWatchlist.add(`Tvdb:${foundItem.ProviderIds.Tvdb}:${foundItem.Type}`); + } + + // Update progress after processing + await new Promise(resolve => requestAnimationFrame(resolve)); + + } catch (err) { + ERR(`Error importing item ${i + 1}:`, err); + results.errors++; + // Update progress after error + await new Promise(resolve => requestAnimationFrame(resolve)); + } + } + + return results; + } + + // Clear entire watchlist + async function clearWatchlist() { + const apiClient = window.ApiClient; + const userId = apiClient.getCurrentUserId(); + const serverUrl = apiClient.serverAddress(); + const token = apiClient.accessToken(); + + const types = ['Movie', 'Series', 'Season', 'Episode']; + let cleared = 0; + + for (const type of types) { + try { + const url = `${serverUrl}/Items?Filters=Likes&IncludeItemTypes=${type}&UserId=${userId}&Recursive=true&Fields=Id`; + const res = await fetch(url, { headers: { "Authorization": `MediaBrowser Token=\"${token}\"` } }); + const data = await res.json(); + const items = data.Items || []; + + for (const item of items) { + try { + await apiClient.updateUserItemRating(userId, item.Id, 'false'); + cleared++; + } catch (err) { + ERR(`Failed to remove item ${item.Id}:`, err); + } + } + } catch (err) { + ERR(`Failed to fetch ${type} items for clearing:`, err); + } + } + + // Clear cache + const sections = ['movies', 'series', 'seasons', 'episodes']; + sections.forEach(section => { + localStorageCache.clear(`watchlist_${section}`); + watchlistCache[section].data = []; + }); + + // Refresh watchlist + await initWatchlistTab(); + renderWatchlistContent(); + + alert(`Watchlist cleared: ${cleared} item(s) removed.`); + } + // Update watchlist cache when an item is toggled async function updateWatchlistCacheOnToggle(itemId, itemType, isAdded) { try { @@ -3386,7 +4187,7 @@ In the Custom Tabs plugin, add a new tab with the following HTML content: } } - setupWebSocketMonitoring(); + //setupWebSocketMonitoring(); // Try to set up immediately /* if (!setupWebSocketMonitoring()) {