Fixed the ability to add monsters while a fight is going.

This commit is contained in:
Robert Johnson 2025-05-26 21:17:42 -04:00
parent 40a798514d
commit 785af983da

View File

@ -1,8 +1,8 @@
import React, { useState, useEffect, useRef } from 'react'; import React, { useState, useEffect, useRef, useMemo } from 'react';
import { initializeApp } from 'firebase/app'; import { initializeApp } from 'firebase/app';
import { getAuth, signInAnonymously, onAuthStateChanged, signInWithCustomToken } from 'firebase/auth'; 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 { getFirestore, doc, setDoc, 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, /* ImageIcon removed */ EyeOff, ExternalLink, AlertTriangle } from 'lucide-react'; // ImageIcon removed import { PlusCircle, Users, Swords, Trash2, Eye, Edit3, Save, XCircle, ChevronsUpDown, UserCheck, UserX, HeartCrack, HeartPulse, Zap, EyeOff, ExternalLink, AlertTriangle } from 'lucide-react'; // ImageIcon removed
// --- Firebase Configuration --- // --- Firebase Configuration ---
const firebaseConfig = { const firebaseConfig = {
@ -92,6 +92,8 @@ function useFirestoreCollection(collectionPath, queryConstraints = []) {
const [isLoading, setIsLoading] = useState(true); const [isLoading, setIsLoading] = useState(true);
const [error, setError] = useState(null); const [error, setError] = useState(null);
const queryString = useMemo(() => JSON.stringify(queryConstraints), [queryConstraints]);
useEffect(() => { useEffect(() => {
if (!db || !collectionPath) { if (!db || !collectionPath) {
setData([]); setData([]);
@ -103,8 +105,7 @@ function useFirestoreCollection(collectionPath, queryConstraints = []) {
setIsLoading(true); setIsLoading(true);
setError(null); setError(null);
const constraints = Array.isArray(queryConstraints) ? queryConstraints : []; const q = query(collection(db, collectionPath), ...queryConstraints);
const q = query(collection(db, collectionPath), ...constraints);
const unsubscribe = onSnapshot(q, (snapshot) => { const unsubscribe = onSnapshot(q, (snapshot) => {
const items = snapshot.docs.map(doc => ({ id: doc.id, ...doc.data() })); const items = snapshot.docs.map(doc => ({ id: doc.id, ...doc.data() }));
@ -118,7 +119,8 @@ function useFirestoreCollection(collectionPath, queryConstraints = []) {
}); });
return () => unsubscribe(); return () => unsubscribe();
}, [collectionPath, JSON.stringify(queryConstraints)]); // eslint-disable-next-line react-hooks/exhaustive-deps
}, [collectionPath, queryString]);
return { data, isLoading, error }; return { data, isLoading, error };
} }
@ -218,6 +220,7 @@ function App() {
TTRPG Initiative Tracker TTRPG Initiative Tracker
</h1> </h1>
<div className="flex items-center space-x-4"> <div className="flex items-center space-x-4">
{/* UID display removed */}
<button <button
onClick={openPlayerWindow} onClick={openPlayerWindow}
className={`px-4 py-2 rounded-md text-sm font-medium transition-colors bg-teal-500 hover:bg-teal-600 text-white flex items-center`} className={`px-4 py-2 rounded-md text-sm font-medium transition-colors bg-teal-500 hover:bg-teal-600 text-white flex items-center`}
@ -233,7 +236,7 @@ function App() {
{!isAuthReady && !error && <p>Authenticating...</p>} {!isAuthReady && !error && <p>Authenticating...</p>}
</main> </main>
<footer className="bg-slate-900 p-4 text-center text-sm text-slate-400 mt-8"> <footer className="bg-slate-900 p-4 text-center text-sm text-slate-400 mt-8">
TTRPG Initiative Tracker v0.1.24 TTRPG Initiative Tracker v0.1.25
</footer> </footer>
</div> </div>
); );
@ -372,9 +375,9 @@ function AdminView({ userId }) {
className={cardClasses} className={cardClasses}
style={cardStyle} style={cardStyle}
> >
{/* Overlay for text readability if background image exists */}
<div className={`relative z-10 ${campaign.playerDisplayBackgroundUrl ? 'bg-black bg-opacity-60 p-3 rounded-md' : ''}`}> <div className={`relative z-10 ${campaign.playerDisplayBackgroundUrl ? 'bg-black bg-opacity-60 p-3 rounded-md' : ''}`}>
<h3 className="text-xl font-semibold text-white">{campaign.name}</h3> <h3 className="text-xl font-semibold text-white">{campaign.name}</h3>
{/* ImageIcon removed from here */}
<button <button
onClick={(e) => { onClick={(e) => {
e.stopPropagation(); e.stopPropagation();
@ -415,12 +418,9 @@ function AdminView({ userId }) {
); );
} }
// ... (CreateCampaignForm, CharacterManager, EncounterManager, CreateEncounterForm, ParticipantManager, EditParticipantModal, InitiativeControls, DisplayView, Modal, Icons remain the same as v0.1.23) // --- CreateCampaignForm, CharacterManager, EncounterManager, CreateEncounterForm, ParticipantManager, EditParticipantModal, InitiativeControls, DisplayView, Modal, Icons ---
// For brevity, only the changed AdminView is shown in full. The rest of the components are identical to the previous version. // The rest of the components are identical to the previous version (v0.1.23) and are included below for completeness.
// The DisplayView, CharacterManager, EncounterManager, etc., and their sub-components // The changes for ESLint warnings were primarily in the imports at the top of App.js and in the useFirestoreCollection hook.
// (CreateEncounterForm, ParticipantManager, EditParticipantModal, InitiativeControls)
// are not changed from the previous version provided (v0.1.23).
// The Modal component and Icon components also remain unchanged.
function CreateCampaignForm({ onCreate, onCancel }) { function CreateCampaignForm({ onCreate, onCancel }) {
const [name, setName] = useState(''); const [name, setName] = useState('');
@ -1060,7 +1060,6 @@ function InitiativeControls({ campaignId, encounter, encounterPath }) {
); );
} }
// DisplayView remains the same as v0.1.19 (before focused view)
function DisplayView() { function DisplayView() {
const { data: activeDisplayData, isLoading: isLoadingActiveDisplay, error: activeDisplayError } = useFirestoreDocument(getActiveDisplayDocPath()); const { data: activeDisplayData, isLoading: isLoadingActiveDisplay, error: activeDisplayError } = useFirestoreDocument(getActiveDisplayDocPath());
@ -1154,8 +1153,24 @@ function DisplayView() {
let participantsToRender = []; let participantsToRender = [];
if (participants) { if (participants) {
if (isStarted && activeEncounterData.turnOrderIds?.length > 0 ) { if (isStarted && activeEncounterData.turnOrderIds?.length > 0 ) {
participantsToRender = activeEncounterData.turnOrderIds const inTurnOrderAndActive = activeEncounterData.turnOrderIds
.map(id => participants.find(p => p.id === id)).filter(p => p && p.isActive); .map(id => participants.find(p => p.id === id))
.filter(p => p && p.isActive);
const notInTurnOrderButActive = participants.filter(p =>
p.isActive &&
!activeEncounterData.turnOrderIds.includes(p.id)
).sort((a,b) => {
if(a.initiative === b.initiative) {
const indexA = participants.findIndex(originalP => originalP.id === a.id);
const indexB = participants.findIndex(originalP => originalP.id === b.id);
return indexA - indexB;
}
return b.initiative - a.initiative;
});
participantsToRender = [...inTurnOrderAndActive, ...notInTurnOrderButActive];
} else { } else {
participantsToRender = [...participants].filter(p => p.isActive) participantsToRender = [...participants].filter(p => p.isActive)
.sort((a, b) => { .sort((a, b) => {