From be6037c8cd968ce001b27cb543551c489dadd54c Mon Sep 17 00:00:00 2001 From: HighImKevin Date: Sat, 14 Mar 2026 14:21:04 -0400 Subject: [PATCH] Add watched/unwatched information to Playlists and Collection pages --- scripts/collections.js | 31 ++++++++++++++++++++++++++++++- scripts/playlist.js | 25 +++++++++++++++++++++++++ 2 files changed, 55 insertions(+), 1 deletion(-) diff --git a/scripts/collections.js b/scripts/collections.js index c7d993d..315cab5 100644 --- a/scripts/collections.js +++ b/scripts/collections.js @@ -595,6 +595,34 @@ activePage.dataset.collectionSortingAdded = 'true'; } + /** + * Update collection page by adding the played item count to the page + * @param {Object} item - Collection item (BoxSet) + */ + async function updateCollectionPage(item) { + const unplayedItemCount = item.UserData?.UnplayedItemCount || 0; + const totalItemCount = item.RecursiveItemCount || item.ChildCount || 0; + const playedItemCount = totalItemCount - unplayedItemCount; + + const isVideoCollection = document.querySelector('.libraryPage:not(.hide) .collectionItems:has(.card[data-mediatype="Video"])').length > 0; + const progressText = isVideoCollection ? 'watched' : 'complete'; + const incompleteText = isVideoCollection ? 'unwatched' : 'incomplete'; + + const itemMiscInfoPrimary = document.querySelector('.libraryPage:not(.hide) .itemMiscInfo-primary'); + if (itemMiscInfoPrimary && unplayedItemCount > 0) { + const mediaInfoItem = document.createElement('div'); + mediaInfoItem.className = 'mediaInfoItem'; + mediaInfoItem.textContent = `${playedItemCount} ${progressText}`; + itemMiscInfoPrimary.appendChild(mediaInfoItem); + + const mediaInfoItemIncomplete = document.createElement('div'); + mediaInfoItemIncomplete.className = 'mediaInfoItem'; + mediaInfoItemIncomplete.textContent = `${unplayedItemCount} ${incompleteText}`; + itemMiscInfoPrimary.appendChild(mediaInfoItemIncomplete); + } + + } + /** * Initialize collections hook */ @@ -619,7 +647,8 @@ // Small delay to ensure details DOM is ready setTimeout(async () => { if (item && item.Id && item.Type === 'BoxSet') { - await addCollectionSorting(item); + addCollectionSorting(item); + updateCollectionPage(item); } }, 100); }, diff --git a/scripts/playlist.js b/scripts/playlist.js index 8c3e11b..e7cde67 100644 --- a/scripts/playlist.js +++ b/scripts/playlist.js @@ -914,6 +914,31 @@ itemsContainer: playlistItemsContainer }); + // Updated played item count + const playedItemCount = children.filter(item => item.UserData?.Played === true).length; + + const itemMiscInfoPrimary = document.querySelector('.libraryPage:not(.hide) .itemMiscInfo-primary'); + if (itemMiscInfoPrimary && playedItemCount > 0) { + const isAudioPlaylist = children.every(item => item.MediaType === 'Audio'); + const isBookPlaylist = children.every(item => item.MediaType === 'Book'); + const progressText = isAudioPlaylist ? 'played' : isBookPlaylist ? 'read' : 'watched'; + const incompleteText = isAudioPlaylist ? 'unplayed' : isBookPlaylist ? 'unread' : 'unwatched'; + + // Add CSS Var --played-item-count + itemMiscInfoPrimary.dataset.playedItemCount = playedItemCount; + itemMiscInfoPrimary.dataset.totalItemCount = children.length; + + const mediaInfoItem = document.createElement('div'); + mediaInfoItem.className = 'mediaInfoItem'; + mediaInfoItem.textContent = `${playedItemCount} ${progressText}`; + itemMiscInfoPrimary.appendChild(mediaInfoItem); + + const mediaInfoItemIncomplete = document.createElement('div'); + mediaInfoItemIncomplete.className = 'mediaInfoItem'; + mediaInfoItemIncomplete.textContent = `${children.length - playedItemCount} ${incompleteText}`; + itemMiscInfoPrimary.appendChild(mediaInfoItemIncomplete); + } + // Add sort button (only if it doesn't exist) if (!sortButton) { addSortButton(detailButtons, playlistId);