refactor: App.js imports shared turn funcs (DRY), delete duplicates

Delete duplicate consts (DEFAULT_MAX_HP/INIT_MOD/MONSTER_DEFAULT_INIT_MOD,
generateId, rollD20, formatInitMod) + funcs (sortParticipantsByInitiative,
computeTurnOrderAfterRemoval, computeTurnOrderAfterAddition) from App.js.
Import from @ttrpg/shared (1-list model). Kills second drift source.

CRA resolves @ttrpg/shared via npm workspaces symlink. Build green.
This commit is contained in:
david raistrick
2026-07-01 16:02:35 -04:00
parent 5d3a0607ef
commit d1cbe7091a
+4 -43
View File
@@ -1,4 +1,5 @@
import React, { useState, useEffect, useRef, useMemo } from 'react';
import * as shared from '@ttrpg/shared';
import { initializeApp } from './storage';
import { getAuth, signInAnonymously, onAuthStateChanged, signInWithCustomToken } from './storage';
import { getFirestore, doc, setDoc, addDoc, collection, onSnapshot, updateDoc, deleteDoc, query, orderBy, limit, writeBatch, getStorage, getStorageMode } from './storage';
@@ -46,9 +47,7 @@ if (typeof document !== 'undefined') {
// ============================================================================
const APP_VERSION = 'v0.3';
const DEFAULT_MAX_HP = 10;
const DEFAULT_INIT_MOD = 0;
const MONSTER_DEFAULT_INIT_MOD = 2;
const { DEFAULT_MAX_HP, DEFAULT_INIT_MOD, MONSTER_DEFAULT_INIT_MOD, generateId, rollD20, formatInitMod, sortParticipantsByInitiative, computeTurnOrderAfterRemoval, computeTurnOrderAfterAddition } = shared;
const ROLL_DISPLAY_DURATION = 5000;
const CONDITIONS = [
@@ -152,24 +151,8 @@ const getPath = {
// UTILITY FUNCTIONS
// ============================================================================
const generateId = () => crypto.randomUUID();
const rollD20 = () => Math.floor(Math.random() * 20) + 1;
const formatInitMod = (mod) => {
if (mod === undefined || mod === null) return 'N/A';
return mod >= 0 ? `+${mod}` : `${mod}`;
};
const sortParticipantsByInitiative = (participants, originalOrder) => {
return [...participants].sort((a, b) => {
if (a.initiative === b.initiative) {
const indexA = originalOrder.findIndex(p => p.id === a.id);
const indexB = originalOrder.findIndex(p => p.id === b.id);
return indexA - indexB;
}
return b.initiative - a.initiative;
});
};
// generateId, rollD20, formatInitMod, sortParticipantsByInitiative,
// computeTurnOrderAfterRemoval/Addition: imported from @ttrpg/shared (1-list model).
const LOG_QUERY = [orderBy('timestamp', 'desc'), limit(500)];
@@ -184,28 +167,6 @@ const logAction = async (message, context = {}, undoData = null) => {
}
};
// Returns turnOrderIds/currentTurnParticipantId updates when a participant leaves active combat.
const computeTurnOrderAfterRemoval = (encounter, removedId, updatedParticipants) => {
if (!encounter.isStarted) return {};
const currentIds = encounter.turnOrderIds || [];
const newIds = currentIds.filter(id => id !== removedId);
const updates = { turnOrderIds: newIds };
if (encounter.currentTurnParticipantId === removedId) {
const removedPos = currentIds.indexOf(removedId);
const candidates = [...currentIds.slice(removedPos + 1), ...currentIds.slice(0, removedPos)];
const nextId = candidates.find(id => updatedParticipants.find(p => p.id === id && p.isActive)) ?? null;
updates.currentTurnParticipantId = nextId;
}
return updates;
};
// Returns turnOrderIds update when a participant re-enters active combat mid-encounter.
const computeTurnOrderAfterAddition = (encounter, addedId) => {
if (!encounter.isStarted) return {};
const currentIds = encounter.turnOrderIds || [];
if (currentIds.includes(addedId)) return {};
return { turnOrderIds: [...currentIds, addedId] };
};
// ============================================================================
// CUSTOM HOOKS