Character drag reorder via players array
Character list items draggable (ChevronsUpDown handle). Drop reorders players array on campaign doc (single updateDoc). Array order = display order.
This commit is contained in:
+28
-1
@@ -682,6 +682,22 @@ function CharacterManager({ campaignId, campaignCharacters }) {
|
||||
const [editingCharacter, setEditingCharacter] = useState(null);
|
||||
const [showDeleteConfirm, setShowDeleteConfirm] = useState(false);
|
||||
const [itemToDelete, setItemToDelete] = useState(null);
|
||||
const [draggedCharId, setDraggedCharId] = useState(null);
|
||||
|
||||
const handleCharDragStart = (e, id) => { setDraggedCharId(id); e.dataTransfer.effectAllowed = 'move'; };
|
||||
const handleCharDragOver = (e) => { e.preventDefault(); e.dataTransfer.dropEffect = 'move'; };
|
||||
const handleCharDrop = async (e, targetId) => {
|
||||
e.preventDefault();
|
||||
if (!campaignId || !draggedCharId || draggedCharId === targetId) { setDraggedCharId(null); return; }
|
||||
const reordered = [...campaignCharacters];
|
||||
const fromIdx = reordered.findIndex(c => c.id === draggedCharId);
|
||||
const toIdx = reordered.findIndex(c => c.id === targetId);
|
||||
if (fromIdx === -1 || toIdx === -1) { setDraggedCharId(null); return; }
|
||||
const [moved] = reordered.splice(fromIdx, 1);
|
||||
reordered.splice(toIdx, 0, moved);
|
||||
try { await storage.updateDoc(getPath.campaign(campaignId), { players: reordered }); } catch (err) {}
|
||||
setDraggedCharId(null);
|
||||
};
|
||||
const [isOpen, setIsOpen] = useState(() => {
|
||||
try { return localStorage.getItem('ttrpg.charactersCollapsed') !== 'true'; }
|
||||
catch { return true; }
|
||||
@@ -841,7 +857,17 @@ function CharacterManager({ campaignId, campaignCharacters }) {
|
||||
|
||||
<ul className="space-y-2">
|
||||
{campaignCharacters.map(character => (
|
||||
<li key={character.id} className="flex justify-between items-center p-3 bg-stone-800 rounded-md">
|
||||
<li
|
||||
key={character.id}
|
||||
draggable
|
||||
onDragStart={(e) => handleCharDragStart(e, character.id)}
|
||||
onDragOver={handleCharDragOver}
|
||||
onDrop={(e) => handleCharDrop(e, character.id)}
|
||||
onDragEnd={() => setDraggedCharId(null)}
|
||||
className={`flex justify-between items-center p-3 bg-stone-800 rounded-md cursor-grab ${draggedCharId === character.id ? 'opacity-50 ring-2 ring-yellow-400' : ''}`}
|
||||
>
|
||||
<div className="flex items-center flex-grow">
|
||||
<ChevronsUpDown size={16} className="text-stone-400 flex-shrink-0 mr-2" title="Drag to reorder" />
|
||||
{editingCharacter && editingCharacter.id === character.id ? (
|
||||
<form
|
||||
onSubmit={(e) => {
|
||||
@@ -917,6 +943,7 @@ function CharacterManager({ campaignId, campaignCharacters }) {
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
|
||||
Reference in New Issue
Block a user