Merge pull request #198 from itsgareth/fix/sidebar-settings-main-bottom-nav-sections-v2
fix(settings): restrict sidebar reorder to main vs bottom sections
This commit is contained in:
commit
a0b7779520
4 changed files with 191 additions and 156 deletions
232
index.html
232
index.html
|
|
@ -2776,124 +2776,130 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<div class="settings-group">
|
||||
<div class="setting-item">
|
||||
<div class="info">
|
||||
<span class="label">Show Home in Sidebar</span>
|
||||
<span class="description">Display the Home link in the sidebar navigation</span>
|
||||
<div class="settings-group" id="sidebar-order-settings-group">
|
||||
<div class="sidebar-settings-section sidebar-settings-main">
|
||||
<span class="sidebar-settings-section-label">TOP SECTION</span>
|
||||
<div class="setting-item">
|
||||
<div class="info">
|
||||
<span class="label">Show Home in Sidebar</span>
|
||||
<span class="description">Display the Home link in the sidebar navigation</span>
|
||||
</div>
|
||||
<label class="toggle-switch">
|
||||
<input type="checkbox" id="sidebar-show-home-toggle" checked />
|
||||
<span class="slider"></span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="setting-item">
|
||||
<div class="info">
|
||||
<span class="label">Show Library in Sidebar</span>
|
||||
<span class="description"
|
||||
>Display the Library link in the sidebar navigation</span
|
||||
>
|
||||
</div>
|
||||
<label class="toggle-switch">
|
||||
<input type="checkbox" id="sidebar-show-library-toggle" checked />
|
||||
<span class="slider"></span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="setting-item">
|
||||
<div class="info">
|
||||
<span class="label">Show Recent in Sidebar</span>
|
||||
<span class="description"
|
||||
>Display the Recent link in the sidebar navigation</span
|
||||
>
|
||||
</div>
|
||||
<label class="toggle-switch">
|
||||
<input type="checkbox" id="sidebar-show-recent-toggle" checked />
|
||||
<span class="slider"></span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="setting-item">
|
||||
<div class="info">
|
||||
<span class="label">Show Unreleased in Sidebar</span>
|
||||
<span class="description"
|
||||
>Display the Unreleased link in the sidebar navigation</span
|
||||
>
|
||||
</div>
|
||||
<label class="toggle-switch">
|
||||
<input type="checkbox" id="sidebar-show-unreleased-toggle" checked />
|
||||
<span class="slider"></span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="setting-item">
|
||||
<div class="info">
|
||||
<span class="label">Show Donate in Sidebar</span>
|
||||
<span class="description"
|
||||
>Display the Donate link in the sidebar navigation</span
|
||||
>
|
||||
</div>
|
||||
<label class="toggle-switch">
|
||||
<input type="checkbox" id="sidebar-show-donate-toggle" checked />
|
||||
<span class="slider"></span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="setting-item">
|
||||
<div class="info">
|
||||
<span class="label">Show Settings in Sidebar</span>
|
||||
<span class="description"
|
||||
>Display the Settings link in the sidebar navigation</span
|
||||
>
|
||||
</div>
|
||||
<label class="toggle-switch">
|
||||
<input type="checkbox" id="sidebar-show-settings-toggle" checked />
|
||||
<span class="slider"></span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="setting-item">
|
||||
<div class="info">
|
||||
<span class="label">Show Account in Sidebar</span>
|
||||
<span class="description"
|
||||
>Display the Account link in the sidebar navigation</span
|
||||
>
|
||||
</div>
|
||||
<label class="toggle-switch">
|
||||
<input type="checkbox" id="sidebar-show-account-toggle" checked />
|
||||
<span class="slider"></span>
|
||||
</label>
|
||||
</div>
|
||||
<label class="toggle-switch">
|
||||
<input type="checkbox" id="sidebar-show-home-toggle" checked />
|
||||
<span class="slider"></span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="setting-item">
|
||||
<div class="info">
|
||||
<span class="label">Show Library in Sidebar</span>
|
||||
<span class="description"
|
||||
>Display the Library link in the sidebar navigation</span
|
||||
>
|
||||
<div class="sidebar-settings-section sidebar-settings-bottom">
|
||||
<span class="sidebar-settings-section-label">BOTTOM SECTION</span>
|
||||
<div class="setting-item">
|
||||
<div class="info">
|
||||
<span class="label">Show About in Sidebar</span>
|
||||
<span class="description"
|
||||
>Display the About link in the sidebar navigation</span
|
||||
>
|
||||
</div>
|
||||
<label class="toggle-switch">
|
||||
<input type="checkbox" id="sidebar-show-about-bottom-toggle" checked />
|
||||
<span class="slider"></span>
|
||||
</label>
|
||||
</div>
|
||||
<label class="toggle-switch">
|
||||
<input type="checkbox" id="sidebar-show-library-toggle" checked />
|
||||
<span class="slider"></span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="setting-item">
|
||||
<div class="info">
|
||||
<span class="label">Show Recent in Sidebar</span>
|
||||
<span class="description"
|
||||
>Display the Recent link in the sidebar navigation</span
|
||||
>
|
||||
<div class="setting-item">
|
||||
<div class="info">
|
||||
<span class="label">Show Download in Sidebar</span>
|
||||
<span class="description"
|
||||
>Display the Download link in the sidebar navigation</span
|
||||
>
|
||||
</div>
|
||||
<label class="toggle-switch">
|
||||
<input type="checkbox" id="sidebar-show-download-bottom-toggle" checked />
|
||||
<span class="slider"></span>
|
||||
</label>
|
||||
</div>
|
||||
<label class="toggle-switch">
|
||||
<input type="checkbox" id="sidebar-show-recent-toggle" checked />
|
||||
<span class="slider"></span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="setting-item">
|
||||
<div class="info">
|
||||
<span class="label">Show Unreleased in Sidebar</span>
|
||||
<span class="description"
|
||||
>Display the Unreleased link in the sidebar navigation</span
|
||||
>
|
||||
<div class="setting-item">
|
||||
<div class="info">
|
||||
<span class="label">Show Discord in Sidebar</span>
|
||||
<span class="description"
|
||||
>Display the Discord link in the sidebar navigation</span
|
||||
>
|
||||
</div>
|
||||
<label class="toggle-switch">
|
||||
<input type="checkbox" id="sidebar-show-discordbtn-toggle" checked />
|
||||
<span class="slider"></span>
|
||||
</label>
|
||||
</div>
|
||||
<label class="toggle-switch">
|
||||
<input type="checkbox" id="sidebar-show-unreleased-toggle" checked />
|
||||
<span class="slider"></span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="setting-item">
|
||||
<div class="info">
|
||||
<span class="label">Show Donate in Sidebar</span>
|
||||
<span class="description"
|
||||
>Display the Donate link in the sidebar navigation</span
|
||||
>
|
||||
</div>
|
||||
<label class="toggle-switch">
|
||||
<input type="checkbox" id="sidebar-show-donate-toggle" checked />
|
||||
<span class="slider"></span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="setting-item">
|
||||
<div class="info">
|
||||
<span class="label">Show Settings in Sidebar</span>
|
||||
<span class="description"
|
||||
>Display the Settings link in the sidebar navigation</span
|
||||
>
|
||||
</div>
|
||||
<label class="toggle-switch">
|
||||
<input type="checkbox" id="sidebar-show-settings-toggle" checked />
|
||||
<span class="slider"></span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="setting-item">
|
||||
<div class="info">
|
||||
<span class="label">Show Account in Sidebar</span>
|
||||
<span class="description"
|
||||
>Display the Account link in the sidebar navigation</span
|
||||
>
|
||||
</div>
|
||||
<label class="toggle-switch">
|
||||
<input type="checkbox" id="sidebar-show-account-toggle" checked />
|
||||
<span class="slider"></span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="setting-item">
|
||||
<div class="info">
|
||||
<span class="label">Show About in Sidebar</span>
|
||||
<span class="description"
|
||||
>Display the About link in the sidebar navigation</span
|
||||
>
|
||||
</div>
|
||||
<label class="toggle-switch">
|
||||
<input type="checkbox" id="sidebar-show-about-toggle" checked />
|
||||
<span class="slider"></span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="setting-item">
|
||||
<div class="info">
|
||||
<span class="label">Show Download in Sidebar</span>
|
||||
<span class="description"
|
||||
>Display the Download link in the sidebar navigation</span
|
||||
>
|
||||
</div>
|
||||
<label class="toggle-switch">
|
||||
<input type="checkbox" id="sidebar-show-download-toggle" checked />
|
||||
<span class="slider"></span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="setting-item">
|
||||
<div class="info">
|
||||
<span class="label">Show Discord in Sidebar</span>
|
||||
<span class="description"
|
||||
>Display the Discord link in the sidebar navigation</span
|
||||
>
|
||||
</div>
|
||||
<label class="toggle-switch">
|
||||
<input type="checkbox" id="sidebar-show-discord-toggle" checked />
|
||||
<span class="slider"></span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1940,7 +1940,7 @@ export function initializeSettings(scrobbler, player, api, ui) {
|
|||
});
|
||||
}
|
||||
|
||||
const sidebarShowAboutToggle = document.getElementById('sidebar-show-about-toggle');
|
||||
const sidebarShowAboutToggle = document.getElementById('sidebar-show-about-bottom-toggle');
|
||||
if (sidebarShowAboutToggle) {
|
||||
sidebarShowAboutToggle.checked = sidebarSectionSettings.shouldShowAbout();
|
||||
sidebarShowAboutToggle.addEventListener('change', (e) => {
|
||||
|
|
@ -1949,7 +1949,7 @@ export function initializeSettings(scrobbler, player, api, ui) {
|
|||
});
|
||||
}
|
||||
|
||||
const sidebarShowDownloadToggle = document.getElementById('sidebar-show-download-toggle');
|
||||
const sidebarShowDownloadToggle = document.getElementById('sidebar-show-download-bottom-toggle');
|
||||
if (sidebarShowDownloadToggle) {
|
||||
sidebarShowDownloadToggle.checked = sidebarSectionSettings.shouldShowDownload();
|
||||
sidebarShowDownloadToggle.addEventListener('change', (e) => {
|
||||
|
|
@ -1958,7 +1958,7 @@ export function initializeSettings(scrobbler, player, api, ui) {
|
|||
});
|
||||
}
|
||||
|
||||
const sidebarShowDiscordToggle = document.getElementById('sidebar-show-discord-toggle');
|
||||
const sidebarShowDiscordToggle = document.getElementById('sidebar-show-discordbtn-toggle');
|
||||
if (sidebarShowDiscordToggle) {
|
||||
sidebarShowDiscordToggle.checked = sidebarSectionSettings.shouldShowDiscord();
|
||||
sidebarShowDiscordToggle.addEventListener('change', (e) => {
|
||||
|
|
@ -1989,18 +1989,29 @@ export function initializeSettings(scrobbler, player, api, ui) {
|
|||
item.draggable = true;
|
||||
});
|
||||
|
||||
const getSidebarItems = () =>
|
||||
Array.from(sidebarSettingsGroup.querySelectorAll('.sidebar-setting-item[data-sidebar-id]'));
|
||||
const mainContainer = sidebarSettingsGroup.querySelector('.sidebar-settings-main');
|
||||
const bottomContainer = sidebarSettingsGroup.querySelector('.sidebar-settings-bottom');
|
||||
|
||||
const getSidebarItems = () => [
|
||||
...(mainContainer?.querySelectorAll('.sidebar-setting-item[data-sidebar-id]') ?? []),
|
||||
...(bottomContainer?.querySelectorAll('.sidebar-setting-item[data-sidebar-id]') ?? []),
|
||||
];
|
||||
|
||||
const applySidebarSettingsOrder = () => {
|
||||
const order = sidebarSectionSettings.getOrder();
|
||||
const itemMap = new Map(getSidebarItems().map((item) => [item.dataset.sidebarId, item]));
|
||||
const bottomIds = sidebarSectionSettings.getBottomNavIds();
|
||||
const mainOrder = order.filter((id) => !bottomIds.includes(id));
|
||||
const bottomOrder = order.filter((id) => bottomIds.includes(id));
|
||||
const allItems = getSidebarItems();
|
||||
const itemMap = new Map(allItems.map((item) => [item.dataset.sidebarId, item]));
|
||||
|
||||
order.forEach((id) => {
|
||||
mainOrder.forEach((id) => {
|
||||
const item = itemMap.get(id);
|
||||
if (item) {
|
||||
sidebarSettingsGroup.appendChild(item);
|
||||
}
|
||||
if (item && mainContainer) mainContainer.appendChild(item);
|
||||
});
|
||||
bottomOrder.forEach((id) => {
|
||||
const item = itemMap.get(id);
|
||||
if (item && bottomContainer) bottomContainer.appendChild(item);
|
||||
});
|
||||
};
|
||||
|
||||
|
|
@ -2032,9 +2043,8 @@ export function initializeSettings(scrobbler, player, api, ui) {
|
|||
saveSidebarOrder();
|
||||
};
|
||||
|
||||
const getDragAfterElement = (container, y) => {
|
||||
const draggableElements = [...container.querySelectorAll('.sidebar-setting-item:not(.dragging)')];
|
||||
|
||||
const getDragAfterElement = (elements, y) => {
|
||||
const draggableElements = elements.filter((el) => el !== draggedItem);
|
||||
return draggableElements.reduce(
|
||||
(closest, child) => {
|
||||
const box = child.getBoundingClientRect();
|
||||
|
|
@ -2051,12 +2061,15 @@ export function initializeSettings(scrobbler, player, api, ui) {
|
|||
const handleDragOver = (e) => {
|
||||
e.preventDefault();
|
||||
if (!draggedItem) return;
|
||||
const afterElement = getDragAfterElement(sidebarSettingsGroup, e.clientY);
|
||||
const container = draggedItem.parentElement;
|
||||
if (container !== mainContainer && container !== bottomContainer) return;
|
||||
const sectionItems = Array.from(container.querySelectorAll('.sidebar-setting-item[data-sidebar-id]'));
|
||||
const afterElement = getDragAfterElement(sectionItems, e.clientY);
|
||||
if (afterElement === draggedItem) return;
|
||||
if (afterElement) {
|
||||
sidebarSettingsGroup.insertBefore(draggedItem, afterElement);
|
||||
container.insertBefore(draggedItem, afterElement);
|
||||
} else {
|
||||
sidebarSettingsGroup.appendChild(draggedItem);
|
||||
container.appendChild(draggedItem);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -1501,11 +1501,17 @@ export const sidebarSectionSettings = {
|
|||
'sidebar-nav-donate',
|
||||
'sidebar-nav-settings',
|
||||
'sidebar-nav-account',
|
||||
'sidebar-nav-about',
|
||||
'sidebar-nav-download',
|
||||
'sidebar-nav-discord',
|
||||
'sidebar-nav-about-bottom',
|
||||
'sidebar-nav-download-bottom',
|
||||
'sidebar-nav-discordbtn',
|
||||
],
|
||||
|
||||
getBottomNavIds() {
|
||||
const ul = document.querySelector('.sidebar-nav.bottom ul');
|
||||
if (!ul) return [];
|
||||
return Array.from(ul.children).map((li) => li.id);
|
||||
},
|
||||
|
||||
shouldShowHome() {
|
||||
try {
|
||||
const val = localStorage.getItem(this.SHOW_HOME_KEY);
|
||||
|
|
@ -1661,37 +1667,24 @@ export const sidebarSectionSettings = {
|
|||
},
|
||||
|
||||
applySidebarOrder() {
|
||||
const lists = document.querySelectorAll('.sidebar-nav ul');
|
||||
const primaryList = lists[0];
|
||||
if (!primaryList) return;
|
||||
const secondaryList = lists[1];
|
||||
const mainList = document.querySelector('.sidebar-nav.main ul');
|
||||
const bottomList = document.querySelector('.sidebar-nav.bottom ul');
|
||||
if (!mainList) return;
|
||||
|
||||
const order = this.getOrder();
|
||||
const secondaryCount = secondaryList ? secondaryList.children.length : 0;
|
||||
const splitIndex = secondaryCount ? Math.max(0, order.length - secondaryCount) : order.length;
|
||||
const primaryOrder = order.slice(0, splitIndex);
|
||||
const secondaryOrder = order.slice(splitIndex);
|
||||
const bottomIds = this.getBottomNavIds();
|
||||
const mainOrder = order.filter((id) => !bottomIds.includes(id));
|
||||
const bottomOrder = order.filter((id) => bottomIds.includes(id));
|
||||
|
||||
primaryOrder.forEach((id) => {
|
||||
mainOrder.forEach((id) => {
|
||||
const item = document.getElementById(id);
|
||||
if (item) {
|
||||
primaryList.appendChild(item);
|
||||
}
|
||||
if (item) mainList.appendChild(item);
|
||||
});
|
||||
|
||||
if (secondaryList) {
|
||||
secondaryOrder.forEach((id) => {
|
||||
if (bottomList) {
|
||||
bottomOrder.forEach((id) => {
|
||||
const item = document.getElementById(id);
|
||||
if (item) {
|
||||
secondaryList.appendChild(item);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
secondaryOrder.forEach((id) => {
|
||||
const item = document.getElementById(id);
|
||||
if (item) {
|
||||
primaryList.appendChild(item);
|
||||
}
|
||||
if (item) bottomList.appendChild(item);
|
||||
});
|
||||
}
|
||||
},
|
||||
|
|
|
|||
23
styles.css
23
styles.css
|
|
@ -1820,6 +1820,29 @@ input[type='search']::-webkit-search-cancel-button {
|
|||
padding: 0;
|
||||
}
|
||||
|
||||
.sidebar-settings-section {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0;
|
||||
}
|
||||
|
||||
.sidebar-settings-section-label {
|
||||
font-size: 0.75rem;
|
||||
font-weight: 600;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.05em;
|
||||
color: var(--muted-foreground);
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.sidebar-settings-section .sidebar-settings-section-label + .setting-item {
|
||||
margin-top: var(--spacing-sm);
|
||||
}
|
||||
|
||||
.sidebar-settings-section .setting-item + .setting-item {
|
||||
margin-top: var(--spacing-md);
|
||||
}
|
||||
|
||||
.setting-item {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
|
|
|
|||
Loading…
Reference in a new issue