diff --git a/scripts/ui.js b/scripts/ui.js
index 590f473..e97f132 100644
--- a/scripts/ui.js
+++ b/scripts/ui.js
@@ -845,6 +845,8 @@
if (isLast) dataAttrs.push('data-is-last="true"');
const dataAttrsStr = dataAttrs.join(' ');
+ const isPinnedSection = sectionId.startsWith('pinned-parent-') || sectionId.startsWith('pinned-list-');
+
return `
@@ -858,14 +860,24 @@
${sectionName.replace(/"/g, '"')}
- ${showUpDownButtons ? `
+
+ ${isPinnedSection ? `
+
+ ` : ''}
+
+ ${showUpDownButtons ? `
- ` : ''}
+ ` : ''}
+
`;
}
@@ -1147,6 +1159,21 @@
align-items: center;
gap: 0.5em;
}
+ .section-row .listItemBody {
+ flex: 1 1 auto;
+ min-width: 0;
+ }
+ .section-row-actions {
+ display: flex;
+ align-items: center;
+ flex: 0 0 auto;
+ margin-left: auto;
+ gap: 0.1em;
+ }
+ .section-row-actions .paper-icon-button-light {
+ margin: 0;
+ padding: 0.5em;
+ }
/* Type filtering - hide sections when their type toggle is off */
/* This will be dynamically generated for each section type, but we include common ones */
.sections-container[data-section-type-jellyfin="false"] .section-row[data-section-type="jellyfin"],
@@ -1174,6 +1201,20 @@
pointer-events: auto;
cursor: pointer;
}
+ .disabled-sections-list .section-row .section-configure-gear-btn,
+ .disabled-sections-list .section-row .section-unpin-btn {
+ pointer-events: auto;
+ cursor: pointer;
+ }
+ .section-configure-gear-btn,
+ .section-unpin-btn {
+ flex: 0 0 auto;
+ opacity: 0.75;
+ }
+ .section-configure-gear-btn:hover,
+ .section-unpin-btn:hover {
+ opacity: 1;
+ }
/* Disable/grey-out up button for first item in enabled list */
.enabled-sections-list .section-row[data-is-first="true"] .section-move-up-btn {
opacity: 0.4;
@@ -1186,12 +1227,69 @@
pointer-events: none;
cursor: not-allowed;
}
+ .layout-mobile .section-row .drag_handle {
+ display: none !important;
+ }
+ @media (max-width: 899px) {
+ .section-row .drag_handle {
+ display: none !important;
+ }
+ }
`;
document.head.appendChild(style);
}
- // Up/Down button handlers
- container.addEventListener('click', (e) => {
+ // Up/Down / gear / pin / admin row-click handlers
+ container.addEventListener('click', async (e) => {
+ const configureBtn = e.target.closest('.section-configure-gear-btn');
+ if (configureBtn) {
+ e.preventDefault();
+ e.stopPropagation();
+ const sectionId = configureBtn.dataset.sectionId;
+ if (!sectionId) return;
+ const sectionConfig = sections.find((s) => (s.id || '') === sectionId) || { id: sectionId };
+ const liveEl = document.querySelector(`[data-section-id="${CSS.escape(sectionId)}"]`);
+ const open = window.KefinHomeScreenSectionConfigure?.openConfigurePopover;
+ if (typeof open === 'function') {
+ open(sectionConfig, liveEl || configureBtn.closest('.section-row'), configureBtn);
+ }
+ return;
+ }
+
+ const unpinBtn = e.target.closest('.section-unpin-btn');
+ if (unpinBtn) {
+ e.preventDefault();
+ e.stopPropagation();
+ const sectionId = unpinBtn.dataset.sectionId;
+ if (!sectionId) return;
+ unpinBtn.disabled = true;
+ try {
+ const liveEl = document.querySelector(`[data-section-id="${CSS.escape(sectionId)}"]`);
+ let ok = false;
+ if (sectionId.startsWith('pinned-parent-')) {
+ ok = !!(await window.KefinHomeScreenPin?.unpinParentSection?.(sectionId, liveEl));
+ } else if (sectionId.startsWith('pinned-list-')) {
+ ok = !!(await window.KefinHomeScreenPin?.unpinPinnedListSection?.(sectionId, liveEl));
+ }
+ if (ok) {
+ const row = unpinBtn.closest('.section-row');
+ const enabledList = row?.closest('.enabled-sections-list');
+ row?.remove();
+ if (enabledList) updateFirstLastAttributes(enabledList);
+ const idx = sections.findIndex((s) => (s.id || '') === sectionId);
+ if (idx >= 0) sections.splice(idx, 1);
+ if (typeof onSave === 'function') {
+ await onSave();
+ }
+ }
+ } catch (err) {
+ console.error('Error unpinning section from order editor:', err);
+ } finally {
+ unpinBtn.disabled = false;
+ }
+ return;
+ }
+
const upBtn = e.target.closest('.section-move-up-btn');
const downBtn = e.target.closest('.section-move-down-btn');
@@ -1280,6 +1378,25 @@
});
}
}
+ return;
+ }
+
+ // Admin: clicking the row (not interactive controls) opens the section editor
+ const sectionRow = e.target.closest('.section-row');
+ if (!sectionRow || !container.contains(sectionRow)) return;
+ if (e.target.closest('.toggle-slider, .section-toggle-switch, .section-move-up-btn, .section-move-down-btn, .section-configure-gear-btn, .section-unpin-btn, .drag_handle, button, input')) {
+ return;
+ }
+ const sectionId = sectionRow.dataset.sectionId;
+ if (!sectionId || typeof window.KefinHomeScreen?.openSectionEditorForId !== 'function') return;
+ try {
+ const isAdmin = !!(await window.apiHelper?.isAdmin?.());
+ if (!isAdmin) return;
+ e.preventDefault();
+ e.stopPropagation();
+ await window.KefinHomeScreen.openSectionEditorForId(sectionId);
+ } catch (err) {
+ console.error('Error opening section editor from order row:', err);
}
});
@@ -1682,6 +1799,11 @@
btn.addEventListener('click', () => {
const next = btn.dataset.enabled !== 'true';
updateToggleSwitchUI(btn, next);
+ const checkboxId = btn.dataset.checkboxId;
+ const checkbox = checkboxId ? document.getElementById(checkboxId) : null;
+ if (checkbox) {
+ checkbox.dispatchEvent(new Event('change', { bubbles: true }));
+ }
});
});
}