Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9437272fe0 | ||
|
|
541e04b732 |
@@ -52,8 +52,10 @@ function mockContext(overrides: Partial<Encounter> = {}) {
|
||||
toggleCondition: vi.fn(),
|
||||
toggleConcentration: vi.fn(),
|
||||
addFromBestiary: vi.fn(),
|
||||
addMultipleFromBestiary: vi.fn(),
|
||||
addFromPlayerCharacter: vi.fn(),
|
||||
makeStore: vi.fn(),
|
||||
withUndo: vi.fn((action: () => unknown) => action()),
|
||||
undo: vi.fn(),
|
||||
redo: vi.fn(),
|
||||
canUndo: false,
|
||||
|
||||
@@ -26,8 +26,12 @@ export function creatureKey(r: SearchResult): string {
|
||||
}
|
||||
|
||||
export function useActionBarState() {
|
||||
const { addCombatant, addFromBestiary, addFromPlayerCharacter } =
|
||||
useEncounterContext();
|
||||
const {
|
||||
addCombatant,
|
||||
addFromBestiary,
|
||||
addMultipleFromBestiary,
|
||||
addFromPlayerCharacter,
|
||||
} = useEncounterContext();
|
||||
const { search: bestiarySearch, isLoaded: bestiaryLoaded } =
|
||||
useBestiaryContext();
|
||||
const { characters: playerCharacters } = usePlayerCharactersContext();
|
||||
@@ -92,11 +96,24 @@ export function useActionBarState() {
|
||||
|
||||
const confirmQueued = useCallback(() => {
|
||||
if (!queued) return;
|
||||
for (let i = 0; i < queued.count; i++) {
|
||||
if (queued.count === 1) {
|
||||
handleAddFromBestiary(queued.result);
|
||||
} else {
|
||||
const creatureId = addMultipleFromBestiary(queued.result, queued.count);
|
||||
const isDesktop = globalThis.matchMedia("(min-width: 1024px)").matches;
|
||||
if (creatureId && panelView.mode === "closed" && isDesktop) {
|
||||
showCreature(creatureId);
|
||||
}
|
||||
}
|
||||
clearInput();
|
||||
}, [queued, handleAddFromBestiary, clearInput]);
|
||||
}, [
|
||||
queued,
|
||||
handleAddFromBestiary,
|
||||
addMultipleFromBestiary,
|
||||
panelView.mode,
|
||||
showCreature,
|
||||
clearInput,
|
||||
]);
|
||||
|
||||
const parseNum = (v: string): number | undefined => {
|
||||
if (v.trim() === "") return undefined;
|
||||
|
||||
@@ -298,9 +298,10 @@ export function useEncounter() {
|
||||
setEvents((prev) => [...prev, ...result]);
|
||||
}, [makeStore]);
|
||||
|
||||
const addFromBestiary = useCallback(
|
||||
(entry: BestiaryIndexEntry): CreatureId | null => {
|
||||
const snapshot = encounterRef.current;
|
||||
const addOneFromBestiary = useCallback(
|
||||
(
|
||||
entry: BestiaryIndexEntry,
|
||||
): { cId: CreatureId; events: DomainEvent[] } | null => {
|
||||
const store = makeStore();
|
||||
const existingNames = store.get().combatants.map((c) => c.name);
|
||||
const { newName, renames } = resolveCreatureName(
|
||||
@@ -328,8 +329,20 @@ export function useEncounter() {
|
||||
creatureId: cId,
|
||||
});
|
||||
|
||||
if (isDomainError(result)) {
|
||||
store.save(snapshot);
|
||||
if (isDomainError(result)) return null;
|
||||
|
||||
return { cId, events: result };
|
||||
},
|
||||
[makeStore],
|
||||
);
|
||||
|
||||
const addFromBestiary = useCallback(
|
||||
(entry: BestiaryIndexEntry): CreatureId | null => {
|
||||
const snapshot = encounterRef.current;
|
||||
const added = addOneFromBestiary(entry);
|
||||
|
||||
if (!added) {
|
||||
makeStore().save(snapshot);
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -337,10 +350,36 @@ export function useEncounter() {
|
||||
undoRedoRef.current = newState;
|
||||
setUndoRedoState(newState);
|
||||
|
||||
setEvents((prev) => [...prev, ...result]);
|
||||
return cId;
|
||||
setEvents((prev) => [...prev, ...added.events]);
|
||||
return added.cId;
|
||||
},
|
||||
[makeStore],
|
||||
[makeStore, addOneFromBestiary],
|
||||
);
|
||||
|
||||
const addMultipleFromBestiary = useCallback(
|
||||
(entry: BestiaryIndexEntry, count: number): CreatureId | null => {
|
||||
const snapshot = encounterRef.current;
|
||||
const allEvents: DomainEvent[] = [];
|
||||
let lastCId: CreatureId | null = null;
|
||||
|
||||
for (let i = 0; i < count; i++) {
|
||||
const added = addOneFromBestiary(entry);
|
||||
if (!added) {
|
||||
makeStore().save(snapshot);
|
||||
return null;
|
||||
}
|
||||
allEvents.push(...added.events);
|
||||
lastCId = added.cId;
|
||||
}
|
||||
|
||||
const newState = pushUndo(undoRedoRef.current, snapshot);
|
||||
undoRedoRef.current = newState;
|
||||
setUndoRedoState(newState);
|
||||
|
||||
setEvents((prev) => [...prev, ...allEvents]);
|
||||
return lastCId;
|
||||
},
|
||||
[makeStore, addOneFromBestiary],
|
||||
);
|
||||
|
||||
const addFromPlayerCharacter = useCallback(
|
||||
@@ -426,9 +465,11 @@ export function useEncounter() {
|
||||
toggleCondition,
|
||||
toggleConcentration,
|
||||
addFromBestiary,
|
||||
addMultipleFromBestiary,
|
||||
addFromPlayerCharacter,
|
||||
undo: undoAction,
|
||||
redo: redoAction,
|
||||
makeStore,
|
||||
withUndo,
|
||||
} as const;
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ function rollDice(): number {
|
||||
}
|
||||
|
||||
export function useInitiativeRolls() {
|
||||
const { encounter, makeStore } = useEncounterContext();
|
||||
const { encounter, makeStore, withUndo } = useEncounterContext();
|
||||
const { getCreature } = useBestiaryContext();
|
||||
const { showCreature } = useSidePanelContext();
|
||||
|
||||
@@ -28,12 +28,8 @@ export function useInitiativeRolls() {
|
||||
(id: CombatantId, mode: RollMode = "normal") => {
|
||||
const diceRolls: [number, ...number[]] =
|
||||
mode === "normal" ? [rollDice()] : [rollDice(), rollDice()];
|
||||
const result = rollInitiativeUseCase(
|
||||
makeStore(),
|
||||
id,
|
||||
diceRolls,
|
||||
getCreature,
|
||||
mode,
|
||||
const result = withUndo(() =>
|
||||
rollInitiativeUseCase(makeStore(), id, diceRolls, getCreature, mode),
|
||||
);
|
||||
if (isDomainError(result)) {
|
||||
setRollSingleSkipped(true);
|
||||
@@ -43,22 +39,19 @@ export function useInitiativeRolls() {
|
||||
}
|
||||
}
|
||||
},
|
||||
[makeStore, getCreature, encounter.combatants, showCreature],
|
||||
[makeStore, getCreature, withUndo, encounter.combatants, showCreature],
|
||||
);
|
||||
|
||||
const handleRollAllInitiative = useCallback(
|
||||
(mode: RollMode = "normal") => {
|
||||
const result = rollAllInitiativeUseCase(
|
||||
makeStore(),
|
||||
rollDice,
|
||||
getCreature,
|
||||
mode,
|
||||
const result = withUndo(() =>
|
||||
rollAllInitiativeUseCase(makeStore(), rollDice, getCreature, mode),
|
||||
);
|
||||
if (!isDomainError(result) && result.skippedNoSource > 0) {
|
||||
setRollSkippedCount(result.skippedNoSource);
|
||||
}
|
||||
},
|
||||
[makeStore, getCreature],
|
||||
[makeStore, getCreature, withUndo],
|
||||
);
|
||||
|
||||
return {
|
||||
|
||||
Reference in New Issue
Block a user