jRay/Jellyfin.Plugin.JRay/Web/jray-overlay.js
Duncan Tourolle a38122e993
All checks were successful
🏗️ Build Plugin / build (push) Successful in 1m13s
🧪 Test Plugin / test (push) Successful in 20s
Latest Release / latest-release (push) Successful in 25s
first commit
2026-06-12 18:16:47 +02:00

110 lines
3.0 KiB
JavaScript

(function () {
'use strict';
var POLL_INTERVAL_MS = 1000;
var overlayEl = null;
function getItemIdFromHash() {
var match = window.location.hash.match(/[?&]id=([0-9a-fA-F-]+)/);
return match ? match[1] : null;
}
function removeOverlay() {
if (overlayEl && overlayEl.parentNode) {
overlayEl.parentNode.removeChild(overlayEl);
}
overlayEl = null;
}
function showOverlay(video, actors) {
removeOverlay();
if (!actors || actors.length === 0) {
return;
}
var container = video.parentElement;
if (!container) {
return;
}
overlayEl = document.createElement('div');
overlayEl.className = 'jrayOverlay';
overlayEl.style.position = 'absolute';
overlayEl.style.bottom = '10%';
overlayEl.style.left = '2%';
overlayEl.style.zIndex = '9999';
overlayEl.style.display = 'flex';
overlayEl.style.flexWrap = 'wrap';
overlayEl.style.gap = '12px';
overlayEl.style.pointerEvents = 'none';
actors.forEach(function (actor) {
var card = document.createElement('div');
card.style.background = 'rgba(0, 0, 0, 0.7)';
card.style.color = '#fff';
card.style.padding = '6px 12px';
card.style.borderRadius = '4px';
card.style.fontSize = '14px';
card.textContent = actor.name;
overlayEl.appendChild(card);
});
container.appendChild(overlayEl);
}
function fetchContext(itemId, t) {
if (!window.ApiClient) {
return;
}
var url = window.ApiClient.getUrl('Plugins/JRay/Items/' + itemId + '/jray', { t: t });
window.ApiClient.ajax({ url: url, type: 'GET', dataType: 'json' }).then(function (context) {
var video = document.querySelector('video');
if (!video || !video.paused) {
return;
}
showOverlay(video, context.actors);
}, function () {
// No truth data (404) or request error - fail silently, never break playback.
});
}
function onPause(event) {
var video = event.target;
var itemId = getItemIdFromHash();
if (!itemId) {
return;
}
fetchContext(itemId, video.currentTime);
}
function onPlay() {
removeOverlay();
}
function attach(video) {
if (video.dataset.jrayAttached) {
return;
}
video.dataset.jrayAttached = 'true';
video.addEventListener('pause', onPause);
video.addEventListener('play', onPlay);
video.addEventListener('playing', onPlay);
video.addEventListener('seeking', removeOverlay);
}
setInterval(function () {
var video = document.querySelector('video');
if (video) {
attach(video);
} else {
removeOverlay();
}
}, POLL_INTERVAL_MS);
})();