Add client-side settings feature and support for SVG file type
This commit is contained in:
@@ -13,6 +13,7 @@
|
||||
* - option to set a maximum for the pagination dots (will turn into a counter style if exceeded)
|
||||
* - option to disable loading screen
|
||||
* - option to put collection (boxsets) IDs into the slideshow to display their items
|
||||
* - option to enable client-side settings (allow users to override settings locally on their device)
|
||||
*/
|
||||
|
||||
@import url(https://fonts.googleapis.com/css2?family=Archivo+Narrow:ital,wght@0,400..700;1,400..700&display=swap);
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
* - option to set a maximum for the pagination dots (will turn into a counter style if exceeded)
|
||||
* - option to disable loading screen
|
||||
* - option to put collection (boxsets) IDs into the slideshow to display their items
|
||||
* - option to enable client-side settings (allow users to override settings locally on their device)
|
||||
*/
|
||||
|
||||
//Core Module Configuration
|
||||
@@ -49,6 +50,7 @@ const CONFIG = {
|
||||
enableSeasonalContent: false,
|
||||
customMediaIds: "",
|
||||
enableLoadingScreen: true,
|
||||
enableClientSideSettings: false,
|
||||
};
|
||||
|
||||
// State management
|
||||
@@ -1440,7 +1442,12 @@ const SlideCreator = {
|
||||
}
|
||||
|
||||
const isMobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);
|
||||
const shouldPlayVideo = CONFIG.enableVideoBackdrop && (!isMobile || CONFIG.enableMobileVideo);
|
||||
|
||||
// Client Setting Overrides
|
||||
const enableVideo = SettingsManager.getSetting('videoBackdrops', CONFIG.enableVideoBackdrop);
|
||||
const enableMobileVideo = SettingsManager.getSetting('mobileVideo', CONFIG.enableMobileVideo);
|
||||
|
||||
const shouldPlayVideo = enableVideo && (!isMobile || enableMobileVideo);
|
||||
|
||||
if (trailerUrl && shouldPlayVideo) {
|
||||
let isYoutube = false;
|
||||
@@ -2774,7 +2781,10 @@ const SlideshowManager = {
|
||||
this.nextSlide();
|
||||
}, CONFIG.shuffleInterval);
|
||||
|
||||
if (CONFIG.waitForTrailerToEnd && STATE.slideshow.slideInterval) {
|
||||
// Check if we should wait for trailer
|
||||
const waitForTrailer = SettingsManager.getSetting('waitForTrailer', CONFIG.waitForTrailerToEnd);
|
||||
|
||||
if (waitForTrailer && STATE.slideshow.slideInterval) {
|
||||
const activeSlide = document.querySelector('.slide.active');
|
||||
const hasActiveVideo = !!(activeSlide && activeSlide.querySelector('.video-backdrop'));
|
||||
if (hasActiveVideo) {
|
||||
@@ -2919,6 +2929,158 @@ const initArrowNavigation = () => {
|
||||
);
|
||||
};
|
||||
|
||||
const SettingsManager = {
|
||||
initialized: false,
|
||||
|
||||
init() {
|
||||
if (this.initialized) return;
|
||||
if (!CONFIG.enableClientSideSettings) return;
|
||||
|
||||
this.initialized = true;
|
||||
this.injectSettingsIcon();
|
||||
console.log("MediaBarEnhanced: Client-Side Settings Manager initialized.");
|
||||
},
|
||||
|
||||
getSetting(key, defaultValue) {
|
||||
if (!CONFIG.enableClientSideSettings) return defaultValue;
|
||||
const value = localStorage.getItem(`mediaBarEnhanced-${key}`);
|
||||
return value !== null ? value === 'true' : defaultValue;
|
||||
},
|
||||
|
||||
setSetting(key, value) {
|
||||
localStorage.setItem(`mediaBarEnhanced-${key}`, value);
|
||||
},
|
||||
|
||||
createIcon() {
|
||||
const button = document.createElement('button');
|
||||
button.type = 'button';
|
||||
button.className = 'paper-icon-button-light headerButton media-bar-settings-button';
|
||||
button.title = 'Media Bar Settings';
|
||||
// button.innerHTML = '<span class="material-icons">tune</span>';
|
||||
button.innerHTML = '<img src="/MediaBarEnhanced/Resources/assets/logo_SW.svg" style="width: 24px; height: 24px; vertical-align: middle;">';
|
||||
button.style.verticalAlign = 'middle';
|
||||
|
||||
button.addEventListener('click', (e) => {
|
||||
e.stopPropagation();
|
||||
this.toggleSettingsPopup(button);
|
||||
});
|
||||
|
||||
return button;
|
||||
},
|
||||
|
||||
injectSettingsIcon() {
|
||||
const observer = new MutationObserver((mutations, obs) => {
|
||||
const headerRight = document.querySelector('.headerRight');
|
||||
if (headerRight && !document.querySelector('.media-bar-settings-button')) {
|
||||
const icon = this.createIcon();
|
||||
headerRight.prepend(icon);
|
||||
}
|
||||
});
|
||||
|
||||
observer.observe(document.body, {
|
||||
childList: true,
|
||||
subtree: true
|
||||
});
|
||||
},
|
||||
|
||||
createPopup(anchorElement) {
|
||||
const existing = document.querySelector('.media-bar-settings-popup');
|
||||
if (existing) existing.remove();
|
||||
|
||||
const popup = document.createElement('div');
|
||||
popup.className = 'media-bar-settings-popup dialog';
|
||||
|
||||
Object.assign(popup.style, {
|
||||
position: 'fixed',
|
||||
zIndex: '10000',
|
||||
backgroundColor: '#202020',
|
||||
padding: '1em',
|
||||
borderRadius: '0.3em',
|
||||
boxShadow: '0 0 20px rgba(0,0,0,0.5)',
|
||||
minWidth: '250px',
|
||||
color: '#fff',
|
||||
});
|
||||
|
||||
const rect = anchorElement.getBoundingClientRect();
|
||||
|
||||
let rightPos = window.innerWidth - rect.right;
|
||||
if (window.innerWidth < 450 || (window.innerWidth - rightPos) < 260) {
|
||||
popup.style.right = '1rem';
|
||||
popup.style.left = 'auto';
|
||||
} else {
|
||||
popup.style.right = `${rightPos}px`;
|
||||
popup.style.left = 'auto';
|
||||
}
|
||||
|
||||
popup.style.top = `${rect.bottom + 10}px`;
|
||||
|
||||
const settings = [
|
||||
{ key: 'enabled', label: 'Enable Media Bar', default: true },
|
||||
{ key: 'videoBackdrops', label: 'Enable Video Backdrops', default: CONFIG.enableVideoBackdrop },
|
||||
{ key: 'trailerButton', label: 'Show Trailer Button', default: CONFIG.showTrailerButton },
|
||||
{ key: 'mobileVideo', label: 'Enable Mobile Video', default: CONFIG.enableMobileVideo },
|
||||
{ key: 'waitForTrailer', label: 'Wait For Trailer To End', default: CONFIG.waitForTrailerToEnd },
|
||||
{ key: 'slideAnimations', label: 'Enable Slide Animations', default: CONFIG.slideAnimationEnabled },
|
||||
];
|
||||
|
||||
let html = '<h3 style="margin-top:0; margin-bottom:1em; border-bottom:1px solid #444; padding-bottom:0.5em;">Media Bar Settings</h3>';
|
||||
|
||||
settings.forEach(setting => {
|
||||
const isChecked = this.getSetting(setting.key, setting.default);
|
||||
html += `
|
||||
<div class="checkboxContainer checkboxContainer-withDescription" style="margin-bottom: 0.5em;">
|
||||
<label class="emby-checkbox-label">
|
||||
<input id="mb-setting-${setting.key}" type="checkbox" is="emby-checkbox" class="emby-checkbox" ${isChecked ? 'checked' : ''} />
|
||||
<span class="checkboxLabel">${setting.label}</span>
|
||||
</label>
|
||||
</div>
|
||||
`;
|
||||
});
|
||||
|
||||
// Reload button
|
||||
html += `
|
||||
<div style="margin-top:1em; text-align:right;">
|
||||
<button is="emby-button" type="button" class="raised button-submit emby-button" id="mb-settings-save">
|
||||
<span>Reload</span>
|
||||
</button>
|
||||
</div>
|
||||
`;
|
||||
|
||||
popup.innerHTML = html;
|
||||
|
||||
// Add Listeners
|
||||
settings.forEach(setting => {
|
||||
const checkbox = popup.querySelector(`#mb-setting-${setting.key}`);
|
||||
checkbox.addEventListener('change', (e) => {
|
||||
this.setSetting(setting.key, e.target.checked);
|
||||
});
|
||||
});
|
||||
|
||||
popup.querySelector('#mb-settings-save').addEventListener('click', () => {
|
||||
location.reload();
|
||||
});
|
||||
|
||||
const closeHandler = (e) => {
|
||||
if (!popup.contains(e.target) && e.target !== anchorElement && !anchorElement.contains(e.target)) {
|
||||
popup.remove();
|
||||
document.removeEventListener('click', closeHandler);
|
||||
}
|
||||
};
|
||||
setTimeout(() => document.addEventListener('click', closeHandler), 0);
|
||||
|
||||
document.body.appendChild(popup);
|
||||
},
|
||||
|
||||
toggleSettingsPopup(anchorElement) {
|
||||
const existing = document.querySelector('.media-bar-settings-popup');
|
||||
if (existing) {
|
||||
existing.remove();
|
||||
} else {
|
||||
this.createPopup(anchorElement);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Initialize the slideshow
|
||||
*/
|
||||
@@ -2927,6 +3089,16 @@ const slidesInit = async () => {
|
||||
console.log("⚠️ Slideshow already initialized, skipping");
|
||||
return;
|
||||
}
|
||||
|
||||
if (CONFIG.enableClientSideSettings) {
|
||||
SettingsManager.init();
|
||||
const isEnabled = SettingsManager.getSetting('enabled', true);
|
||||
if (!isEnabled) {
|
||||
console.log("MediaBarEnhanced: Disabled by client-side setting.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
STATE.slideshow.hasInitialized = true;
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user