Fixed the ability to add monsters while a fight is going.
This commit is contained in:
parent
40a798514d
commit
785af983da
49
src/App.js
49
src/App.js
@ -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) => {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user