// KefinTweaks Custom Menu Links Configuration UI // Modular configuration modal for managing custom menu links (function() { 'use strict'; const LOG = (...args) => console.log('[KefinTweaks CustomMenuLinks Config]', ...args); const ERR = (...args) => console.error('[KefinTweaks CustomMenuLinks Config]', ...args); const MODAL_ID = 'kefin-custommenulinks-config'; /** * Load configuration from window.KefinTweaksConfig */ async function loadConfig() { const config = window.KefinTweaksConfig || {}; return config.customMenuLinks || []; } /** * Save configuration to JS Injector */ async function saveConfig(customMenuLinks) { try { // Ensure window.KefinTweaksConfig exists if (!window.KefinTweaksConfig) { window.KefinTweaksConfig = {}; } // Update customMenuLinks config window.KefinTweaksConfig.customMenuLinks = customMenuLinks; // Save to JS Injector using utils if (window.KefinTweaksUtils && window.KefinTweaksUtils.saveConfigToJavaScriptInjector) { await window.KefinTweaksUtils.saveConfigToJavaScriptInjector(); LOG('Configuration saved to JS Injector'); return true; } else { // Fallback: use findJavaScriptInjectorPlugin and saveConfigToJavaScriptInjector from configuration.js if (window.KefinTweaksConfiguration && window.KefinTweaksConfiguration.findJavaScriptInjectorPlugin) { const pluginId = await window.KefinTweaksConfiguration.findJavaScriptInjectorPlugin(); if (pluginId) { await window.KefinTweaksConfiguration.saveConfigToJavaScriptInjector(window.KefinTweaksConfig); LOG('Configuration saved to JS Injector (fallback)'); return true; } } ERR('saveConfigToJavaScriptInjector not available'); return false; } } catch (error) { ERR('Error saving config:', error); return false; } } /** * Build configuration HTML */ function buildConfigHTML(config) { return `
Custom Menu Links JSON
Add custom menu links that will appear in the custom menu. Use Material icon names for icons.
These links are not added by modifying your config.json, so if you wish for these to appear on supported third party clients which don't use jellyfin-web, you will want to manually edit your config.json rather than adding the links here. You can find the information about doing that here.
View Example Format
[
  {
    "name": "My Custom Link",
    "icon": "link",
    "url": "#/userpluginsettings.html?pageUrl=https://domain.com/custom-page",
    "openInNewTab": false
  },
  {
    "name": "External Link",
    "icon": "open_in_new",
    "url": "https://example.com",
    "openInNewTab": true
  }
]
`; } /** * Collect configuration from form */ function collectConfig() { try { const jsonText = document.getElementById('customMenuLinksJson')?.value || '[]'; return JSON.parse(jsonText); } catch (e) { ERR('Error parsing custom menu links JSON:', e); alert('Invalid JSON format. Please check your input.'); return []; } } /** * Open configuration modal */ async function openConfigModal() { try { // Load config const config = await loadConfig(); // Build content const content = document.createElement('div'); content.innerHTML = buildConfigHTML(config); // Build footer const footer = document.createElement('div'); footer.style.display = 'flex'; footer.style.gap = '0.75em'; footer.style.justifyContent = 'flex-end'; footer.innerHTML = ` `; // Create modal const modalInstance = window.ModalSystem.create({ id: MODAL_ID, title: 'Custom Menu Links Configuration', content: content, footer: footer, closeOnBackdrop: true, closeOnEscape: true, showCloseButton: true, onOpen: (modal) => { // Save button const saveBtn = modal.dialogFooter.querySelector('#save-custommenulinks-config-btn'); if (saveBtn) { saveBtn.addEventListener('click', async () => { const customMenuLinks = collectConfig(); const success = await saveConfig(customMenuLinks); if (success) { if (window.KefinTweaksToaster && window.KefinTweaksToaster.toast) { window.KefinTweaksToaster.toast('Custom Menu Links configuration saved!'); } window.ModalSystem.close(MODAL_ID); } else { alert('Error saving configuration. Please ensure the JavaScript Injector plugin is installed and you have administrator permissions.'); } }); } } }); modalInstance.dialog.style.maxWidth = '90vw'; modalInstance.dialog.style.width = '1400px'; modalInstance.dialog.style.height = '90vh'; LOG('Custom Menu Links configuration modal opened'); } catch (error) { ERR('Error opening custom menu links config modal:', error); alert('Error opening configuration: ' + error.message); } } // Export window.KefinTweaksFeatureConfigs = window.KefinTweaksFeatureConfigs || {}; window.KefinTweaksFeatureConfigs.customMenuLinks = { openConfigModal }; console.log('[KefinTweaks CustomMenuLinks Config] Script loaded'); })();