feat: release version 1.0.4
This commit is contained in:
@@ -0,0 +1,82 @@
|
||||
import type { CardListSortKey, SortDirection } from './user-data.ts';
|
||||
|
||||
export type CardType = '큐트' | '퓨어' | '해피';
|
||||
export type HighestStat = '퍼포먼스' | '테크닉' | '센스';
|
||||
|
||||
export type SkillLevel = {
|
||||
level: number;
|
||||
description: string;
|
||||
coolTimeSeconds: number | null;
|
||||
probabilityPercent: number | null;
|
||||
durationSeconds: number | null;
|
||||
effect?: string;
|
||||
condition?: string;
|
||||
};
|
||||
|
||||
export type CardDetails = {
|
||||
title: string;
|
||||
passive: SkillLevel[];
|
||||
active?: SkillLevel[];
|
||||
special: SkillLevel[];
|
||||
costume: { name: string; description: string } | null;
|
||||
};
|
||||
|
||||
export type CardSummary = {
|
||||
id: string;
|
||||
rarity: number;
|
||||
type: CardType;
|
||||
name: string;
|
||||
versionName: string;
|
||||
generation: string;
|
||||
highestStat: HighestStat;
|
||||
details: CardDetails;
|
||||
};
|
||||
|
||||
export function skillAtLevel(
|
||||
levels: readonly SkillLevel[] | undefined,
|
||||
selectedLevel: number
|
||||
): SkillLevel | undefined {
|
||||
return levels?.find((level) => level.level === selectedLevel) ?? levels?.at(-1);
|
||||
}
|
||||
|
||||
export function activeEffectPercent(skill: SkillLevel | undefined): number | null {
|
||||
const match = (skill?.effect || skill?.description)?.match(/스코어(?:가|\s+서포트\s+효과)\s*(\d+(?:\.\d+)?)%/);
|
||||
return match ? Number(match[1]) : null;
|
||||
}
|
||||
|
||||
export function activeSortValue(
|
||||
card: CardSummary,
|
||||
sortKey: CardListSortKey,
|
||||
selectedLevel: number
|
||||
): number | null {
|
||||
const active = skillAtLevel(card.details.active, selectedLevel);
|
||||
if (!active) return null;
|
||||
|
||||
const value = {
|
||||
coolTime: active.coolTimeSeconds,
|
||||
probability: active.probabilityPercent,
|
||||
duration: active.durationSeconds,
|
||||
effect: activeEffectPercent(active)
|
||||
}[sortKey];
|
||||
|
||||
return typeof value === 'number' && Number.isFinite(value) ? value : null;
|
||||
}
|
||||
|
||||
export function sortCardsByActive(
|
||||
cards: readonly CardSummary[],
|
||||
sortKey: CardListSortKey | null,
|
||||
sortDirection: SortDirection,
|
||||
selectedLevel: number
|
||||
): CardSummary[] {
|
||||
if (!sortKey) return [...cards];
|
||||
|
||||
const direction = sortDirection === 'asc' ? 1 : -1;
|
||||
return cards
|
||||
.map((card, index) => ({ card, index, value: activeSortValue(card, sortKey, selectedLevel) }))
|
||||
.sort((left, right) => {
|
||||
if (left.value === null) return right.value === null ? left.index - right.index : 1;
|
||||
if (right.value === null) return -1;
|
||||
return (left.value - right.value) * direction || left.index - right.index;
|
||||
})
|
||||
.map(({ card }) => card);
|
||||
}
|
||||
@@ -12,6 +12,10 @@ export type SavedDeck = {
|
||||
updatedAt: string;
|
||||
};
|
||||
|
||||
export type CardListSortKey = 'coolTime' | 'probability' | 'duration' | 'effect';
|
||||
export type SortDirection = 'asc' | 'desc';
|
||||
export type CardSkillLevel = 1 | 2;
|
||||
|
||||
export type CardListPreferences = {
|
||||
types: string[];
|
||||
stats: string[];
|
||||
@@ -20,6 +24,9 @@ export type CardListPreferences = {
|
||||
activeProbabilities: string[];
|
||||
cardVariants: string[];
|
||||
generations: string[];
|
||||
sortKey: CardListSortKey | null;
|
||||
sortDirection: SortDirection;
|
||||
skillLevel: CardSkillLevel;
|
||||
};
|
||||
|
||||
export type BoardCardPlacements = Record<string, Record<string, string>>;
|
||||
|
||||
Reference in New Issue
Block a user