Compare commits

...

3 Commits

Author SHA1 Message Date
CodeDevMLH
a7929e1ff6 Update manifest.json for release v1.6.1.4 [skip ci] 2026-02-12 01:29:37 +00:00
CodeDevMLH
c78e07de62 Bump version to 1.6.1.4
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 50s
2026-02-12 02:28:47 +01:00
CodeDevMLH
a90f805ea8 Refactor visibility management in slideshow and video playback; optimize state updates and debounce observer for improved performance. 2026-02-12 02:28:32 +01:00
4 changed files with 64 additions and 40 deletions

View File

@@ -12,7 +12,7 @@
<!-- <TreatWarningsAsErrors>false</TreatWarningsAsErrors> -->
<Title>Jellyfin Media Bar Enhanced Plugin</Title>
<Authors>CodeDevMLH</Authors>
<Version>1.6.1.3</Version>
<Version>1.6.1.4</Version>
<RepositoryUrl>https://github.com/CodeDevMLH/jellyfin-plugin-media-bar-enhanced</RepositoryUrl>
</PropertyGroup>

View File

@@ -999,14 +999,3 @@
.layout-tv .backdrop-container{
top: -5%;
}
/* .layout-tv .video-backdrop {
mask-image: linear-gradient(to top,
#fff0 2%,
rgb(0 0 0 / 0.5) 6%,
#000000 8%);
-webkit-mask-image: linear-gradient(to top,
#fff0 2%,
rgb(0 0 0 / 0.5) 6%,
#000000 8%);
} */

View File

@@ -1432,16 +1432,19 @@ const VisibilityObserver = {
// If a full screen video player is active, hide slideshow and stop playback
if ((videoPlayer && !videoPlayer.classList.contains('hide')) || (trailerPlayer && !trailerPlayer.classList.contains('hide'))) {
const container = document.getElementById("slides-container");
if (container) {
container.style.display = "none";
container.style.visibility = "hidden";
container.style.pointerEvents = "none";
if (this._lastVisibleState !== 'player-active') {
this._lastVisibleState = 'player-active';
const container = document.getElementById("slides-container");
if (container) {
container.style.display = "none";
container.style.visibility = "hidden";
container.style.pointerEvents = "none";
}
if (STATE.slideshow.slideInterval) {
STATE.slideshow.slideInterval.stop();
}
SlideshowManager.stopAllPlayback();
}
if (STATE.slideshow.slideInterval) {
STATE.slideshow.slideInterval.stop();
}
SlideshowManager.stopAllPlayback();
return;
}
@@ -1456,20 +1459,27 @@ const VisibilityObserver = {
activeTab &&
activeTab.getAttribute("data-index") === "0";
container.style.display = isVisible ? "block" : "none";
container.style.visibility = isVisible ? "visible" : "hidden";
container.style.pointerEvents = isVisible ? "auto" : "none";
const newState = isVisible ? 'visible' : 'hidden';
// Only update DOM and trigger actions when state actually changes
if (this._lastVisibleState !== newState) {
this._lastVisibleState = newState;
container.style.display = isVisible ? "block" : "none";
container.style.visibility = isVisible ? "visible" : "hidden";
container.style.pointerEvents = isVisible ? "auto" : "none";
if (isVisible) {
if (STATE.slideshow.slideInterval && !STATE.slideshow.isPaused) {
STATE.slideshow.slideInterval.start();
SlideshowManager.resumeActivePlayback();
if (isVisible) {
if (STATE.slideshow.slideInterval && !STATE.slideshow.isPaused) {
STATE.slideshow.slideInterval.start();
SlideshowManager.resumeActivePlayback();
}
} else {
if (STATE.slideshow.slideInterval) {
STATE.slideshow.slideInterval.stop();
}
SlideshowManager.stopAllPlayback();
}
} else {
if (STATE.slideshow.slideInterval) {
STATE.slideshow.slideInterval.stop();
}
SlideshowManager.stopAllPlayback();
}
},
@@ -1477,7 +1487,13 @@ const VisibilityObserver = {
* Initializes visibility observer
*/
init() {
const observer = new MutationObserver(() => this.updateVisibility());
// MARK: Mark
// const observer = new MutationObserver(() => this.updateVisibility());
let debounceTimer = null;
const observer = new MutationObserver(() => {
if (debounceTimer) clearTimeout(debounceTimer);
debounceTimer = setTimeout(() => this.updateVisibility(), 250);
});
observer.observe(document.body, { childList: true, subtree: true });
document.body.addEventListener("click", () => this.updateVisibility());
@@ -1700,6 +1716,7 @@ const SlideCreator = {
const iframe = event.target.getIframe();
if (iframe) {
iframe.setAttribute('tabindex', '-1');
iframe.setAttribute('inert', '');
}
// Store start/end time and videoId for later use
@@ -2772,8 +2789,26 @@ const SlideshowManager = {
const currentSlide = document.querySelector(`.slide[data-item-id="${currentItemId}"]`);
if (!currentSlide) return;
// Use playCurrentVideo to properly restore video with correct mute state
this.playCurrentVideo(currentSlide, currentItemId);
// YouTube player: just resume, don't reload
const ytPlayer = STATE.slideshow.videoPlayers?.[currentItemId];
if (ytPlayer && typeof ytPlayer.playVideo === 'function') {
if (STATE.slideshow.isMuted) {
if (typeof ytPlayer.mute === 'function') ytPlayer.mute();
} else {
if (typeof ytPlayer.unMute === 'function') ytPlayer.unMute();
if (typeof ytPlayer.setVolume === 'function') ytPlayer.setVolume(40);
}
ytPlayer.playVideo();
return;
}
// HTML5 video: just resume, don't reset currentTime
const html5Video = currentSlide.querySelector('video.video-backdrop');
if (html5Video) {
html5Video.muted = STATE.slideshow.isMuted;
if (!STATE.slideshow.isMuted) html5Video.volume = 0.4;
html5Video.play().catch(e => console.warn("Error resuming HTML5 video:", e));
}
},
/**

View File

@@ -9,12 +9,12 @@
"imageUrl": "https://git.mahom03-spacecloud.de/CodeDevMLH/jellyfin-plugin-media-bar-enhanced/raw/branch/main/logo.png",
"versions": [
{
"version": "1.6.1.3",
"version": "1.6.1.4",
"changelog": "- fix tv mode issue\n- refactor video playback management",
"targetAbi": "10.11.0.0",
"sourceUrl": "https://git.mahom03-spacecloud.de/CodeDevMLH/jellyfin-plugin-media-bar-enhanced/releases/download/v1.6.1.3/Jellyfin.Plugin.MediaBarEnhanced.zip",
"checksum": "e5c4f3d11b22621e013bdd0784cf35a6",
"timestamp": "2026-02-12T00:43:52Z"
"sourceUrl": "https://git.mahom03-spacecloud.de/CodeDevMLH/jellyfin-plugin-media-bar-enhanced/releases/download/v1.6.1.4/Jellyfin.Plugin.MediaBarEnhanced.zip",
"checksum": "d0d3f67b52c82c0f01c89b74ae83af01",
"timestamp": "2026-02-12T01:29:36Z"
},
{
"version": "1.6.0.2",