mirror of
https://github.com/ranaldsgift/KefinTweaks.git
synced 2026-11-05 15:52:47 +01:00
Fix Spotlight items watchlist functionality
This commit is contained in:
1 parent
e1f6272f51
commit
809aea7f30
2 files changed
+48
-87
No files matched your search
+16
-28
@@ -779,10 +779,6 @@
|
||||
.spotlight-play-button {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
border-radius: 50%;
|
||||
background: rgba(255, 255, 255, 0.9);
|
||||
color: #000;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
@@ -803,9 +799,6 @@
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
border-radius: 50%;
|
||||
background: rgba(255, 255, 255, 0.2);
|
||||
color: white;
|
||||
border: 2px solid rgba(255, 255, 255, 0.5);
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
@@ -814,25 +807,12 @@
|
||||
transition: all 0.2s;
|
||||
}
|
||||
|
||||
.spotlight-watchlist-button:hover {
|
||||
background: rgba(255, 255, 255, 0.3);
|
||||
}
|
||||
|
||||
.spotlight-watchlist-button.watchlisted {
|
||||
border-color: #4caf50;
|
||||
}
|
||||
|
||||
.spotlight-watchlist-button.watchlisted .material-icons {
|
||||
.spotlight-watchlist-button[data-active="true"] .material-icons {
|
||||
color: #4caf50;
|
||||
}
|
||||
|
||||
.spotlight-watchlist-button:not(.watchlisted):hover {
|
||||
border-color: rgba(255, 255, 255, 0.7);
|
||||
}
|
||||
|
||||
.spotlight-watchlist-button .material-icons {
|
||||
font-size: 28px;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.spotlight-info-button {
|
||||
@@ -842,15 +822,16 @@
|
||||
justify-content: center;
|
||||
transition: all 0.2s;
|
||||
position: relative;
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
.spotlight-overview-tooltip {
|
||||
position: absolute;
|
||||
position: absolute !important;
|
||||
text-align: left;
|
||||
bottom: 100%;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
margin-bottom: 12px;
|
||||
transform: translateX(-50%) !important;
|
||||
margin-bottom: 12px !important;
|
||||
padding: 16px;
|
||||
background: rgba(0, 0, 0, 0.95);
|
||||
color: white;
|
||||
@@ -864,17 +845,19 @@
|
||||
pointer-events: none;
|
||||
transition: opacity 0.2s ease, visibility 0s linear 0.2s;
|
||||
transition-delay: 0s;
|
||||
z-index: 1000;
|
||||
z-index: 1000 !important;
|
||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.5);
|
||||
word-wrap: break-word;
|
||||
max-height: unset !important;
|
||||
}
|
||||
|
||||
/* Show only while hovering the info icon glyph — not the button/tooltip footprint */
|
||||
.spotlight-info-button:has(.material-icons:hover) .spotlight-overview-tooltip {
|
||||
.spotlight-info-button:is(.emby-button):hover .spotlight-overview-tooltip {
|
||||
opacity: 1;
|
||||
visibility: visible;
|
||||
pointer-events: none;
|
||||
transition-delay: 0.5s, 0.5s;
|
||||
display: block;
|
||||
}
|
||||
|
||||
/* Hover overview only on Normal desktop spotlights */
|
||||
@@ -1703,7 +1686,7 @@
|
||||
transform: translateX(-50%) !important;
|
||||
width: fit-content !important;
|
||||
max-width: min(85%, 700px);
|
||||
text-align: center !important;
|
||||
text-align: left !important;
|
||||
font-style: italic;
|
||||
font-size: 1.05em;
|
||||
margin: 0 !important;
|
||||
@@ -1725,6 +1708,8 @@
|
||||
-webkit-line-clamp: 2;
|
||||
-webkit-box-orient: vertical;
|
||||
cursor: default;
|
||||
height: unset;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
/* Normal and large: tagline above dots (dots at bottom: 20px) */
|
||||
@@ -1885,6 +1870,9 @@
|
||||
margin: 0px !important;
|
||||
padding: 0px !important;
|
||||
}
|
||||
.spotlight-section .mainDetailButtons > :is(button.emby-button) {
|
||||
padding: 0.5em !important;
|
||||
}
|
||||
.spotlight-section .mainDetailButtons > .btnPlay:is(.emby-button) {
|
||||
padding: 0.25em !important;
|
||||
}
|
||||
@@ -1934,7 +1922,7 @@
|
||||
}
|
||||
|
||||
.spotlight-metadata-row .emby-tab-button {
|
||||
color: #ececec;
|
||||
color: #c0c0c0;
|
||||
}
|
||||
|
||||
:where(.spotlight-section-title.headerTabs.sectionTabs),
|
||||
|
||||
+32
-59
@@ -16,6 +16,7 @@
|
||||
const state = {
|
||||
defaultCardBackgroundNumber: 1,
|
||||
useBlurhash: true,
|
||||
watchlist: false,
|
||||
};
|
||||
|
||||
/** In-memory scroller metrics (avoid CSS var style writes for JS-only caches). */
|
||||
@@ -2043,6 +2044,7 @@
|
||||
}
|
||||
|
||||
function updateCardWatchlistButtons(itemId, userData) {
|
||||
if (!state.watchlist) return;
|
||||
if (!itemId || !userData || !('Likes' in userData)) return;
|
||||
|
||||
const isLiked = userData.Likes === true;
|
||||
@@ -3867,7 +3869,7 @@
|
||||
|
||||
// Watchlist button (active state from UserData.Likes; click bound by watchlist.js)
|
||||
const watchlistSupportedTypes = ['Movie', 'Series', 'Season', 'Episode', 'BoxSet', 'Playlist', 'Video'];
|
||||
if (watchlistSupportedTypes.includes(itemType)) {
|
||||
if (state.watchlist && watchlistSupportedTypes.includes(itemType)) {
|
||||
const isLiked = item.UserData?.Likes === true;
|
||||
const watchlistButton = document.createElement('button');
|
||||
watchlistButton.type = 'button';
|
||||
@@ -3934,7 +3936,7 @@
|
||||
|
||||
buttonContainer.appendChild(moreButton);
|
||||
|
||||
const NON_PLAYABLE_TYPES = ['CollectionFolder', 'Folder', 'UserView', 'Virtual', 'Studio'];
|
||||
const NON_PLAYABLE_TYPES = ['CollectionFolder', 'Folder', 'UserView', 'Virtual', 'Studio', 'Genre', 'Person'];
|
||||
if (!NON_PLAYABLE_TYPES.includes(item.Type) && item.LocationType !== 'Virtual') {
|
||||
cardOverlayContainer.appendChild(playButton);
|
||||
}
|
||||
@@ -4110,7 +4112,7 @@
|
||||
|
||||
if (itemType === 'Series' && item.Status === 'Continuing') {
|
||||
secondaryTextContent = item.ProductionYear + ' - Present';
|
||||
} else if (itemType === 'Series' && item.EndDate) {
|
||||
} else if (itemType === 'Series' && item.EndDate && item.ProductionYear && item.EndDate.substring(0, 4) !== String(item.ProductionYear)) {
|
||||
secondaryTextContent = item.ProductionYear + ' - ' + item.EndDate.substring(0, 4);
|
||||
} else if (item.Type === 'Program') {
|
||||
secondaryTextContent = new Date(item.StartDate).toLocaleDateString('en-US', { weekday: 'short', month: 'short', day: 'numeric', hour: '2-digit', minute: '2-digit', hour12: true });
|
||||
@@ -4894,67 +4896,32 @@
|
||||
}
|
||||
});
|
||||
|
||||
// Watchlist button (material icon span button with bookmark icon)
|
||||
const watchlistButton = document.createElement('button');
|
||||
watchlistButton.className = 'emby-button button-flat btnWatchlist';
|
||||
// Watchlist button (same Likes / watchlist-button pattern as cards; clicks via watchlist.js)
|
||||
const spotlightWatchlistSupportedTypes = ['Movie', 'Series', 'Season', 'Episode', 'BoxSet', 'Playlist', 'Video'];
|
||||
let watchlistButton = null;
|
||||
if (state.watchlist && spotlightWatchlistSupportedTypes.includes(itemType)) {
|
||||
const isLiked = item.UserData?.Likes === true;
|
||||
watchlistButton = document.createElement('button');
|
||||
watchlistButton.type = 'button';
|
||||
watchlistButton.className = 'watchlist-button spotlight-watchlist-button emby-button button-flat paper-icon-button-light';
|
||||
watchlistButton.setAttribute('data-action', 'none');
|
||||
watchlistButton.setAttribute('data-id', item.Id);
|
||||
watchlistButton.setAttribute('data-active', isLiked ? 'true' : 'false');
|
||||
watchlistButton.title = isLiked ? 'Remove from Watchlist' : 'Add to Watchlist';
|
||||
|
||||
// Check watchlist status - try to get from cache or API
|
||||
let isInWatchlist = false;
|
||||
const sectionName =
|
||||
itemType === 'Movie'
|
||||
? 'movies'
|
||||
: itemType === 'Series'
|
||||
? 'series'
|
||||
: itemType === 'Season'
|
||||
? 'seasons'
|
||||
: itemType === 'Episode'
|
||||
? 'episodes'
|
||||
: null;
|
||||
const watchlistIcon = document.createElement('span');
|
||||
watchlistIcon.className = 'material-icons watchlist';
|
||||
watchlistIcon.setAttribute('aria-hidden', 'true');
|
||||
watchlistButton.appendChild(watchlistIcon);
|
||||
|
||||
// Check watchlist cache if available
|
||||
if (sectionName && typeof window.watchlistCache !== 'undefined' && window.watchlistCache[sectionName]?.data) {
|
||||
isInWatchlist = window.watchlistCache[sectionName].data.some((watchlistItem) => watchlistItem.Id === item.Id);
|
||||
}
|
||||
|
||||
const watchlistIcon = document.createElement('span');
|
||||
watchlistIcon.className = 'material-icons';
|
||||
watchlistIcon.textContent = 'bookmark';
|
||||
watchlistIcon.title = isInWatchlist ? 'Remove from Watchlist' : 'Add to Watchlist';
|
||||
watchlistButton.appendChild(watchlistIcon);
|
||||
if (isInWatchlist) {
|
||||
watchlistButton.classList.add('watchlisted');
|
||||
}
|
||||
watchlistButton.addEventListener('click', async (e) => {
|
||||
e.stopPropagation();
|
||||
const userId = ApiClient.getCurrentUserId();
|
||||
const newStatus = !isInWatchlist;
|
||||
|
||||
try {
|
||||
// Update watchlist status using proper API
|
||||
await ApiClient.updateUserItemRating(userId, item.Id, newStatus ? 'true' : 'false');
|
||||
|
||||
// Update local state
|
||||
isInWatchlist = newStatus;
|
||||
|
||||
// Update button class
|
||||
if (isInWatchlist) {
|
||||
watchlistButton.classList.add('watchlisted');
|
||||
} else {
|
||||
watchlistButton.classList.remove('watchlisted');
|
||||
}
|
||||
|
||||
// Update watchlist cache if available
|
||||
if (sectionName && typeof window.updateWatchlistCacheOnToggle === 'function') {
|
||||
await window.updateWatchlistCacheOnToggle(item.Id, itemType, isInWatchlist);
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('Failed to update watchlist status:', err);
|
||||
if (typeof window.KefinWatchlistLikedIds?.bindWatchlistButton === 'function') {
|
||||
window.KefinWatchlistLikedIds.bindWatchlistButton(watchlistButton, item.Id, itemType);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Info button (shows overview on hover)
|
||||
const infoButton = document.createElement('button');
|
||||
infoButton.className = 'emby-button button-flat spotlight-info-button';
|
||||
infoButton.className = 'emby-button button-flat spotlight-info-button paper-icon-button-light';
|
||||
const infoIcon = document.createElement('span');
|
||||
infoIcon.className = 'material-icons';
|
||||
infoIcon.textContent = 'info';
|
||||
@@ -4970,7 +4937,9 @@
|
||||
}
|
||||
|
||||
buttonsContainer.appendChild(playButton);
|
||||
buttonsContainer.appendChild(watchlistButton);
|
||||
if (watchlistButton) {
|
||||
buttonsContainer.appendChild(watchlistButton);
|
||||
}
|
||||
buttonsContainer.appendChild(infoButton);
|
||||
|
||||
// Rating with star icon
|
||||
@@ -9173,6 +9142,10 @@
|
||||
}
|
||||
|
||||
async function initialize() {
|
||||
// Match loader default: watchlist enabled unless scripts.watchlist === false
|
||||
const scripts = window.KefinTweaksConfig?.scripts || {};
|
||||
state.watchlist = scripts.watchlist !== false;
|
||||
|
||||
if (window.userHelper?.waitForLogin) {
|
||||
await window.userHelper.waitForLogin();
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user