mirror of
https://github.com/ranaldsgift/KefinTweaks.git
synced 2026-11-05 15:52:47 +01:00
Improve Watchlist page handling items being watchlisted/unwatchlisted within a given session
This commit is contained in:
1 parent
a9b055e0e7
commit
0ac2c6415e
3 files changed
+103
-18
No files matched your search
+75
-18
@@ -3297,6 +3297,37 @@ In the Custom Tabs plugin, add a new tab with the following HTML content:
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Keep paint-snapshot membership + header counts in sync on like/unlike without re-rendering sections.
|
||||
* Ghost cards may remain in the DOM; counts reflect liked membership.
|
||||
*/
|
||||
function patchWatchlistItemsByTypeMembership(itemId, itemType, isAdded) {
|
||||
if (!itemId) return;
|
||||
|
||||
const removeFromType = (type) => {
|
||||
const list = watchlistItemsByType[type];
|
||||
if (!Array.isArray(list) || !list.length) return false;
|
||||
const next = list.filter((item) => item?.Id !== itemId);
|
||||
if (next.length === list.length) return false;
|
||||
watchlistItemsByType[type] = next;
|
||||
return true;
|
||||
};
|
||||
|
||||
if (isAdded) {
|
||||
const type = itemType && isWatchlistSupportedType(itemType) ? itemType : null;
|
||||
if (!type) return;
|
||||
const list = watchlistItemsByType[type] || (watchlistItemsByType[type] = []);
|
||||
if (list.some((item) => item?.Id === itemId)) return;
|
||||
list.push({ Id: itemId });
|
||||
} else if (itemType && isWatchlistSupportedType(itemType)) {
|
||||
removeFromType(itemType);
|
||||
} else {
|
||||
WATCHLIST_SECTION_TYPES.forEach(({ type }) => removeFromType(type));
|
||||
}
|
||||
|
||||
updateWatchlistHeaderStats();
|
||||
}
|
||||
|
||||
function getWatchlistProgressiveHost() {
|
||||
const watchlistSection = getWatchlistSection();
|
||||
if (!watchlistSection) return null;
|
||||
@@ -3330,9 +3361,11 @@ In the Custom Tabs plugin, add a new tab with the following HTML content:
|
||||
throw new Error('apiHelper.getWatchlistQuery unavailable');
|
||||
}
|
||||
|
||||
// Same Fields as apiHelper.buildWatchlistQueryDef so invalidate hits this fetch URL
|
||||
const queryOptions = {
|
||||
IncludeItemTypes: itemType,
|
||||
Fields: 'PrimaryImageAspectRatio,DateCreated,ProductionYear,PremiereDate,ProviderIds,UserData'
|
||||
Fields: apiHelper.WATCHLIST_PROGRESSIVE_FIELDS
|
||||
|| 'PrimaryImageAspectRatio,DateCreated,ProductionYear,PremiereDate,ProviderIds,UserData'
|
||||
};
|
||||
const queryResult = await apiHelper.getWatchlistQuery(queryOptions, {
|
||||
ttl: WATCHLIST_CACHE_TTL,
|
||||
@@ -4974,31 +5007,52 @@ In the Custom Tabs plugin, add a new tab with the following HTML content:
|
||||
alert(`Watchlist cleared: ${cleared} item(s) removed.`);
|
||||
}
|
||||
|
||||
// Invalidate progressive watchlist cache and re-render when membership changes
|
||||
/**
|
||||
* Membership changed: update liked-Id cache + invalidate Likes query URL.
|
||||
* Do not full-rebuild the Watchlist tab (avoids scroll jump / stale re-paint races).
|
||||
* Cards stay as ghosts until next visit; cardBuilder owns overlay button UI via UserDataChanged.
|
||||
*/
|
||||
async function updateWatchlistCacheOnToggle(itemId, itemType, isAdded) {
|
||||
try {
|
||||
LOG(`Watchlist membership changed for ${itemType} ${itemId} (added=${isAdded}); refreshing progressive sections`);
|
||||
LOG(`Watchlist membership changed for ${itemType || 'unknown'} ${itemId} (added=${isAdded}); invalidating query cache`);
|
||||
setLikedIdInCache(itemId, isAdded === true);
|
||||
syncOverlayWatchlistButtons();
|
||||
patchWatchlistItemsByTypeMembership(itemId, itemType, isAdded === true);
|
||||
|
||||
if (itemType) {
|
||||
if (itemType && isWatchlistSupportedType(itemType)) {
|
||||
await window.apiHelper?.invalidateWatchlistQueries?.({ IncludeItemTypes: itemType });
|
||||
} else {
|
||||
await invalidateAllWatchlistQueries();
|
||||
}
|
||||
|
||||
const watchlistSection = getWatchlistSection();
|
||||
const watchlistVisible = !!watchlistSection
|
||||
&& !watchlistSection.closest('.libraryPage.hide')
|
||||
&& !!watchlistSection.querySelector('div[data-tab="watchlist"]:not([style*="display: none"])');
|
||||
|
||||
if (watchlistVisible || tabStates.watchlist.isDataFetched) {
|
||||
await initWatchlistTab(true);
|
||||
} else {
|
||||
tabStates.watchlist.isDataFetched = false;
|
||||
}
|
||||
tabStates.watchlist.isDataFetched = false;
|
||||
} catch (err) {
|
||||
ERR('Error refreshing watchlist after toggle:', err);
|
||||
ERR('Error refreshing watchlist cache after toggle:', err);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sync liked-Id cache + invalidate progressive Likes queries from UserData.Likes.
|
||||
* Idempotent for the Set when cardBuilder already applied Likes; always invalidate
|
||||
* so a remote/Library like is visible on the next Watchlist visit.
|
||||
*/
|
||||
async function handleItemWatchlistChange(itemId, isLiked, itemType) {
|
||||
if (!itemId || typeof isLiked !== 'boolean') return;
|
||||
|
||||
if (isItemInLikedIdCache(itemId) !== isLiked) {
|
||||
setLikedIdInCache(itemId, isLiked);
|
||||
}
|
||||
// Keep header counts aligned even if liked-Id Set was already updated by cardBuilder
|
||||
patchWatchlistItemsByTypeMembership(itemId, itemType, isLiked);
|
||||
|
||||
try {
|
||||
if (itemType && isWatchlistSupportedType(itemType)) {
|
||||
await window.apiHelper?.invalidateWatchlistQueries?.({ IncludeItemTypes: itemType });
|
||||
} else {
|
||||
await invalidateAllWatchlistQueries();
|
||||
}
|
||||
tabStates.watchlist.isDataFetched = false;
|
||||
} catch (err) {
|
||||
ERR('Error invalidating watchlist after Likes change:', err);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5022,8 +5076,11 @@ In the Custom Tabs plugin, add a new tab with the following HTML content:
|
||||
|
||||
for (const userData of entries) {
|
||||
if (!userData?.ItemId) continue;
|
||||
LOG(`Detected UserDataChanged for item: ${userData.ItemId}, Played: ${userData.Played}`);
|
||||
handleItemWatchedStatusChange(userData.ItemId, userData.Played, userData.Likes).catch(err => {
|
||||
LOG(`Detected UserDataChanged for item: ${userData.ItemId}, Played: ${userData.Played}, Likes: ${userData.Likes}`);
|
||||
(async () => {
|
||||
await handleItemWatchlistChange(userData.ItemId, userData.Likes);
|
||||
await handleItemWatchedStatusChange(userData.ItemId, userData.Played, userData.Likes);
|
||||
})().catch(err => {
|
||||
ERR('Error handling UserDataChanged event:', err);
|
||||
});
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user