Add settings-driven theme and version metadata

This commit is contained in:
Micha
2025-12-25 14:35:01 +01:00
parent b5d689dd4d
commit 882ef26982
16 changed files with 525 additions and 29 deletions

View File

@@ -217,8 +217,58 @@ export default function Acp({ isAdmin }) {
setOverId(null)
}
const handleDragOver = (event) => {
const applyLocalOrder = (parentId, orderedIds) => {
setForums((prev) =>
prev.map((forum) => {
const pid = getParentId(forum)
if (String(pid ?? '') !== String(parentId ?? '')) {
return forum
}
const newIndex = orderedIds.indexOf(String(forum.id))
return newIndex === -1 ? forum : { ...forum, position: newIndex + 1 }
})
)
}
const handleDragOver = (event, targetId, parentId) => {
event.preventDefault()
event.dataTransfer.dropEffect = 'move'
if (!draggingId || String(draggingId) === String(targetId)) {
return
}
const draggedForum = forums.find((forum) => String(forum.id) === String(draggingId))
if (!draggedForum) {
return
}
const draggedParentId = getParentId(draggedForum)
if (String(draggedParentId ?? '') !== String(parentId ?? '')) {
return
}
const siblings = forums.filter((forum) => {
const pid = getParentId(forum)
return String(pid ?? '') === String(parentId ?? '')
})
const ordered = siblings
.slice()
.sort((a, b) => {
if (a.position !== b.position) return a.position - b.position
return a.name.localeCompare(b.name)
})
.map((forum) => String(forum.id))
const fromIndex = ordered.indexOf(String(draggingId))
const toIndex = ordered.indexOf(String(targetId))
if (fromIndex === -1 || toIndex === -1 || fromIndex === toIndex) {
return
}
ordered.splice(toIndex, 0, ordered.splice(fromIndex, 1)[0])
setOverId(String(targetId))
applyLocalOrder(parentId, ordered)
}
const handleDragEnter = (forumId) => {
@@ -227,7 +277,10 @@ export default function Acp({ isAdmin }) {
}
}
const handleDragLeave = (forumId) => {
const handleDragLeave = (event, forumId) => {
if (event.currentTarget.contains(event.relatedTarget)) {
return
}
if (overId === String(forumId)) {
setOverId(null)
}
@@ -290,9 +343,12 @@ export default function Acp({ isAdmin }) {
overId === String(node.id) ? 'bb-drop-target' : ''
} ${draggingId === String(node.id) ? 'bb-dragging' : ''}`}
style={{ marginLeft: depth * 16 }}
onDragOver={handleDragOver}
draggable
onDragStart={(event) => handleDragStart(event, node.id)}
onDragEnd={handleDragEnd}
onDragOver={(event) => handleDragOver(event, node.id, getParentId(node))}
onDragEnter={() => handleDragEnter(node.id)}
onDragLeave={() => handleDragLeave(node.id)}
onDragLeave={(event) => handleDragLeave(event, node.id)}
onDrop={(event) => handleDrop(event, node.id, getParentId(node))}
>
<div className="d-flex align-items-start gap-3">
@@ -326,9 +382,6 @@ export default function Acp({ isAdmin }) {
<span
className="bb-drag-handle text-muted"
style={{ cursor: 'grab', display: 'inline-flex' }}
draggable
onDragStart={(event) => handleDragStart(event, node.id)}
onDragEnd={handleDragEnd}
title={t('acp.drag_handle')}
>
<i className="bi bi-arrow-down-up" aria-hidden="true" />