forked from phenom/healer-man
Release Healer Man 0.1.9
This commit is contained in:
1 parent
c245a199b6
commit
d060296ade
74 files changed
+5901
-334
No files matched your search
@@ -5,21 +5,33 @@ import {
|
||||
formatTimedEffectTimer,
|
||||
timedEffectRemainingMs,
|
||||
} from "../game/timedEffectDisplay";
|
||||
import {
|
||||
timedEffectDescription,
|
||||
type StatusEffectInspectHandler,
|
||||
type StatusEffectInspection,
|
||||
} from "./statusEffectInspection";
|
||||
|
||||
export type TimedEffectKind = TimedCombatEffect["kind"];
|
||||
|
||||
interface TimedEffectStripProps {
|
||||
readonly targetId: string | null;
|
||||
readonly targetIds?: readonly (string | null)[];
|
||||
readonly kinds?: readonly TimedEffectKind[];
|
||||
readonly className?: string;
|
||||
readonly onInspect?: StatusEffectInspectHandler;
|
||||
readonly tooltipId?: string;
|
||||
}
|
||||
|
||||
function LiveTimedEffectStrip({
|
||||
effects,
|
||||
className = "",
|
||||
onInspect,
|
||||
tooltipId,
|
||||
}: {
|
||||
readonly effects: readonly TimedCombatEffect[];
|
||||
readonly className?: string;
|
||||
readonly onInspect?: StatusEffectInspectHandler;
|
||||
readonly tooltipId?: string;
|
||||
}) {
|
||||
const [now, setNow] = useState(() => Date.now());
|
||||
|
||||
@@ -45,12 +57,29 @@ function LiveTimedEffectStrip({
|
||||
{visibleEffects.map(({ effect, ability, remainingMs }) => {
|
||||
const label = ability?.name ?? effect.sourceAbilityId;
|
||||
const timer = formatTimedEffectTimer(remainingMs);
|
||||
const disposition = effect.kind === "hot" ? "buff" : "debuff";
|
||||
const inspection: StatusEffectInspection = {
|
||||
id: effect.id,
|
||||
name: label,
|
||||
disposition,
|
||||
description: timedEffectDescription(effect.kind, ability?.description),
|
||||
remainingLabel: `${timer} remaining`,
|
||||
stacks: 1,
|
||||
};
|
||||
return (
|
||||
<span
|
||||
key={effect.id}
|
||||
className={`timed-effect timed-effect--${effect.kind}`}
|
||||
className={`timed-effect timed-effect--${effect.kind} ${onInspect ? "timed-effect--inspectable" : ""}`.trim()}
|
||||
tabIndex={onInspect ? 0 : undefined}
|
||||
aria-label={`${label}, ${effect.kind === "hot" ? "healing" : "damage"} over time, ${timer} remaining`}
|
||||
title={`${label} · ${timer} remaining`}
|
||||
aria-describedby={onInspect ? tooltipId : undefined}
|
||||
title={onInspect ? undefined : `${label} · ${timer} remaining`}
|
||||
onPointerEnter={onInspect ? () => onInspect(inspection) : undefined}
|
||||
onPointerLeave={onInspect ? (event) => {
|
||||
if (event.currentTarget !== document.activeElement) onInspect(null);
|
||||
} : undefined}
|
||||
onFocus={onInspect ? () => onInspect(inspection) : undefined}
|
||||
onBlur={onInspect ? () => onInspect(null) : undefined}
|
||||
>
|
||||
{ability?.icon
|
||||
? <img src={ability.icon} alt="" draggable={false} />
|
||||
@@ -69,14 +98,25 @@ function LiveTimedEffectStrip({
|
||||
*/
|
||||
export function TimedEffectStrip({
|
||||
targetId,
|
||||
targetIds,
|
||||
kinds = ["dot", "hot"],
|
||||
className,
|
||||
onInspect,
|
||||
tooltipId,
|
||||
}: TimedEffectStripProps) {
|
||||
const allEffects = useCombatStore((state) => state.effects);
|
||||
const requestedTargetIds = targetIds ?? [targetId];
|
||||
const effects = allEffects.filter((effect) => (
|
||||
effect.targetId === targetId && kinds.includes(effect.kind)
|
||||
requestedTargetIds.includes(effect.targetId) && kinds.includes(effect.kind)
|
||||
));
|
||||
|
||||
if (!effects.length) return null;
|
||||
return <LiveTimedEffectStrip effects={effects} className={className} />;
|
||||
return (
|
||||
<LiveTimedEffectStrip
|
||||
effects={effects}
|
||||
className={className}
|
||||
onInspect={onInspect}
|
||||
tooltipId={tooltipId}
|
||||
/>
|
||||
);
|
||||
}
|
||||
Reference in new issue
Block a user