Adds a 'Hide player HP' toggle in the Combat Controls panel (on by default) that suppresses health bars for player characters in the DisplayView. Setting is persisted in the activeDisplay Firestore doc so it survives page reloads and takes effect in real time on the player screen.
This commit is contained in:
+30
@@ -1505,6 +1505,17 @@ function ParticipantManager({ encounter, encounterPath, campaignCharacters }) {
|
|||||||
|
|
||||||
function InitiativeControls({ campaignId, encounter, encounterPath }) {
|
function InitiativeControls({ campaignId, encounter, encounterPath }) {
|
||||||
const [showEndConfirm, setShowEndConfirm] = useState(false);
|
const [showEndConfirm, setShowEndConfirm] = useState(false);
|
||||||
|
const { data: activeDisplayData } = useFirestoreDocument(getPath.activeDisplay());
|
||||||
|
const hidePlayerHp = activeDisplayData?.hidePlayerHp ?? true;
|
||||||
|
|
||||||
|
const handleToggleHidePlayerHp = async () => {
|
||||||
|
if (!db) return;
|
||||||
|
try {
|
||||||
|
await setDoc(doc(db, getPath.activeDisplay()), { hidePlayerHp: !hidePlayerHp }, { merge: true });
|
||||||
|
} catch (err) {
|
||||||
|
console.error("Error toggling hidePlayerHp:", err);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const handleStartEncounter = async () => {
|
const handleStartEncounter = async () => {
|
||||||
if (!db || !encounter.participants || encounter.participants.length === 0) {
|
if (!db || !encounter.participants || encounter.participants.length === 0) {
|
||||||
@@ -1676,6 +1687,22 @@ function InitiativeControls({ campaignId, encounter, encounterPath }) {
|
|||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{/* Display Settings */}
|
||||||
|
<div className="mt-3 pt-3 border-t border-stone-700">
|
||||||
|
<h5 className="text-xs font-semibold text-stone-400 uppercase tracking-wider mb-2">Player Display</h5>
|
||||||
|
<label className="flex items-center justify-between cursor-pointer gap-2">
|
||||||
|
<span className="text-sm text-stone-300">Hide player HP</span>
|
||||||
|
<button
|
||||||
|
role="switch"
|
||||||
|
aria-checked={hidePlayerHp}
|
||||||
|
onClick={handleToggleHidePlayerHp}
|
||||||
|
className={`relative inline-flex h-5 w-9 flex-shrink-0 rounded-full border-2 border-transparent transition-colors focus:outline-none ${hidePlayerHp ? 'bg-amber-600' : 'bg-stone-600'}`}
|
||||||
|
>
|
||||||
|
<span className={`inline-block h-4 w-4 transform rounded-full bg-white shadow transition-transform ${hidePlayerHp ? 'translate-x-4' : 'translate-x-0'}`} />
|
||||||
|
</button>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<ConfirmationModal
|
<ConfirmationModal
|
||||||
@@ -2299,6 +2326,7 @@ function DisplayView() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const { name, participants, round, currentTurnParticipantId, isStarted, isPaused } = activeEncounterData;
|
const { name, participants, round, currentTurnParticipantId, isStarted, isPaused } = activeEncounterData;
|
||||||
|
const hidePlayerHp = activeDisplayData?.hidePlayerHp ?? true;
|
||||||
|
|
||||||
let participantsToRender = [];
|
let participantsToRender = [];
|
||||||
if (participants) {
|
if (participants) {
|
||||||
@@ -2382,6 +2410,7 @@ function DisplayView() {
|
|||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{!(hidePlayerHp && p.type === 'character') && (
|
||||||
<div className="flex justify-between items-center">
|
<div className="flex justify-between items-center">
|
||||||
<div className="w-full bg-stone-700 rounded-full h-6 md:h-8 relative overflow-hidden border-2 border-stone-600">
|
<div className="w-full bg-stone-700 rounded-full h-6 md:h-8 relative overflow-hidden border-2 border-stone-600">
|
||||||
<div
|
<div
|
||||||
@@ -2395,6 +2424,7 @@ function DisplayView() {
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
{p.conditions?.length > 0 && (
|
{p.conditions?.length > 0 && (
|
||||||
<div className="flex flex-wrap gap-1 mt-2">
|
<div className="flex flex-wrap gap-1 mt-2">
|
||||||
|
|||||||
Reference in New Issue
Block a user