From f530d4303d25ba1052d3b74123c7882023610835 Mon Sep 17 00:00:00 2001 From: robert Date: Mon, 26 May 2025 08:53:26 -0400 Subject: [PATCH] Changed view for more than 7 combatants --- src/App.js | 114 ++++++++++++++++++++++++++++++++--------------------- 1 file changed, 68 insertions(+), 46 deletions(-) diff --git a/src/App.js b/src/App.js index 4d25c19..747b1e5 100644 --- a/src/App.js +++ b/src/App.js @@ -2,7 +2,7 @@ import React, { useState, useEffect, useRef } from 'react'; import { initializeApp } from 'firebase/app'; import { getAuth, signInAnonymously, onAuthStateChanged, signInWithCustomToken } from 'firebase/auth'; import { getFirestore, doc, setDoc, addDoc, getDoc, getDocs, collection, onSnapshot, updateDoc, deleteDoc, query, writeBatch } from 'firebase/firestore'; -import { PlusCircle, Users, Swords, Shield, Trash2, Eye, Edit3, Save, XCircle, ChevronsUpDown, UserCheck, UserX, HeartCrack, HeartPulse, Zap, Image as ImageIcon, EyeOff, ExternalLink } from 'lucide-react'; // Removed unused icons +import { PlusCircle, Users, Swords, Shield, Trash2, Eye, Edit3, Save, XCircle, ChevronsUpDown, UserCheck, UserX, HeartCrack, HeartPulse, Zap, Image as ImageIcon, EyeOff, ExternalLink } from 'lucide-react'; // --- Firebase Configuration --- const firebaseConfig = { @@ -103,7 +103,6 @@ function useFirestoreCollection(collectionPath, queryConstraints = []) { setIsLoading(true); setError(null); - // Ensure queryConstraints is an array before spreading const constraints = Array.isArray(queryConstraints) ? queryConstraints : []; const q = query(collection(db, collectionPath), ...constraints); @@ -119,8 +118,6 @@ function useFirestoreCollection(collectionPath, queryConstraints = []) { }); return () => unsubscribe(); - // Using JSON.stringify for queryConstraints is a common way to handle array/object dependencies. - // For simple cases, it's fine. For complex queries, a more robust memoization or comparison might be needed. }, [collectionPath, JSON.stringify(queryConstraints)]); return { data, isLoading, error }; @@ -237,7 +234,7 @@ function App() { {!isAuthReady && !error &&

Authenticating...

} ); @@ -459,7 +456,7 @@ function EncounterManager({ campaignId, initialActiveEncounterId, campaignCharac }, [selectedEncounterId]); useEffect(() => { - if (!campaignId) { // If no campaign is selected, clear selection + if (!campaignId) { setSelectedEncounterId(null); return; } @@ -473,7 +470,7 @@ function EncounterManager({ campaignId, initialActiveEncounterId, campaignCharac setSelectedEncounterId(activeDisplayInfo.activeEncounterId); } } - } else if (encounters && encounters.length === 0) { // No encounters in this campaign + } else if (encounters && encounters.length === 0) { setSelectedEncounterId(null); } }, [campaignId, initialActiveEncounterId, activeDisplayInfo, encounters]); @@ -682,27 +679,25 @@ function ParticipantManager({ encounter, encounterPath, campaignCharacters }) { // --- Drag and Drop Handlers --- const handleDragStart = (e, id) => { setDraggedItemId(id); - e.dataTransfer.effectAllowed = 'move'; // Indicates that the element can be moved - // e.dataTransfer.setData('text/plain', id); // Optional: useful for some browsers or inter-app drag + e.dataTransfer.effectAllowed = 'move'; }; const handleDragOver = (e) => { - e.preventDefault(); // This is necessary to allow a drop - e.dataTransfer.dropEffect = 'move'; // Visual feedback to the user + e.preventDefault(); + e.dataTransfer.dropEffect = 'move'; }; const handleDrop = async (e, targetId) => { - e.preventDefault(); // Prevent default browser behavior + e.preventDefault(); if (!db || draggedItemId === null || draggedItemId === targetId) { - setDraggedItemId(null); // Reset if no valid drag or dropping on itself + setDraggedItemId(null); return; } - const currentParticipants = [...participants]; // Create a mutable copy + const currentParticipants = [...participants]; const draggedItemIndex = currentParticipants.findIndex(p => p.id === draggedItemId); const targetItemIndex = currentParticipants.findIndex(p => p.id === targetId); - // Ensure both items are found if (draggedItemIndex === -1 || targetItemIndex === -1) { console.error("Dragged or target item not found in participants list."); setDraggedItemId(null); @@ -712,50 +707,37 @@ function ParticipantManager({ encounter, encounterPath, campaignCharacters }) { const draggedItem = currentParticipants[draggedItemIndex]; const targetItem = currentParticipants[targetItemIndex]; - // Crucial: Only allow reordering within the same initiative score for tie-breaking if (draggedItem.initiative !== targetItem.initiative) { console.log("Drag-and-drop for tie-breaking only allowed between participants with the same initiative score."); setDraggedItemId(null); return; } - // Perform the reorder - const [removedItem] = currentParticipants.splice(draggedItemIndex, 1); // Remove dragged item - currentParticipants.splice(targetItemIndex, 0, removedItem); // Insert it at the target's position + const [removedItem] = currentParticipants.splice(draggedItemIndex, 1); + currentParticipants.splice(targetItemIndex, 0, removedItem); try { - // Update Firestore with the new participants order await updateDoc(doc(db, encounterPath), { participants: currentParticipants }); console.log("Participants reordered in Firestore for tie-breaking."); } catch (err) { console.error("Error updating participants after drag-drop:", err); - // Optionally, you might want to revert the local state if Firestore update fails, - // or display an error to the user. For now, we log the error. } - setDraggedItemId(null); // Clear the dragged item ID + setDraggedItemId(null); }; const handleDragEnd = () => { - // This event fires after a drag operation, regardless of whether it was successful or not. - setDraggedItemId(null); // Always clear the dragged item ID + setDraggedItemId(null); }; - // Sort participants for display. Primary sort by initiative (desc), secondary by existing order in array (for stable tie-breaking after D&D) const sortedAdminParticipants = [...participants].sort((a, b) => { if (a.initiative === b.initiative) { - // If initiatives are tied, maintain their current relative order from the `participants` array. - // This relies on `Array.prototype.sort` being stable, which it is in modern JS engines. - // To be absolutely sure or for older engines, one might compare original indices if stored. - // However, since drag-and-drop directly modifies the `participants` array order in Firestore, - // this simple stable sort approach should preserve the manually set tie-breaker order. const indexA = participants.findIndex(p => p.id === a.id); const indexB = participants.findIndex(p => p.id === b.id); return indexA - indexB; } - return b.initiative - a.initiative; // Higher initiative first + return b.initiative - a.initiative; }); - // Identify which initiative scores have ties to enable dragging only for them const initiativeGroups = participants.reduce((acc, p) => { acc[p.initiative] = (acc[p.initiative] || 0) + 1; return acc; @@ -796,7 +778,6 @@ function ParticipantManager({ encounter, encounterPath, campaignCharacters }) {