fix : correct color

This commit is contained in:
2026-10-02 22:12:43 +07:00 Unverified
parent 78750aef95
commit f71c00d2ab
14 changed files with 79 additions and 51 deletions
+2 -2
View File
@@ -17,7 +17,7 @@ import { Field, FieldDescription, FieldGroup, FieldLabel } from "@/components/ui
import { InputGroup, InputGroupAddon, InputGroupInput } from "@/components/ui/input-group";
import { Spinner } from "@/components/ui/spinner";
import { Textarea } from "@/components/ui/textarea";
import { rarityGradientClass } from "@/lib/catalog/rarity";
import { characterRarityGradientClass } from "@/lib/catalog/rarity";
import { cn } from "@/lib/utils";
type Character = { key: string; name: string; aliases: string[]; element: string | null; rarity: number | null; imageUrl: string };
@@ -85,7 +85,7 @@ export function CreateGuideFlow({ characters, existingKeys }: { characters: Char
const disabled = existing.has(character.key);
return (
<Card key={character.key} className="overflow-hidden py-0">
<div className={cn("relative aspect-square", rarityGradientClass(character.rarity))}><Image src={character.imageUrl} alt={character.name} fill className="object-cover" /></div>
<div className={cn("relative aspect-square", characterRarityGradientClass(character.key, character.rarity))}><Image src={character.imageUrl} alt={character.name} fill className="object-cover" /></div>
<CardHeader className="pt-4">
<CardTitle>{character.name}</CardTitle>
<CardDescription>{character.element ?? "Unknown element"}</CardDescription>
+3 -2
View File
@@ -19,7 +19,7 @@ import { Pagination, PaginationContent, PaginationEllipsis, PaginationItem, Pagi
import { Select, SelectContent, SelectGroup, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
import { Spinner } from "@/components/ui/spinner";
import type { GlossaryKind } from "@/lib/glossary";
import { rarityGradientClass } from "@/lib/catalog/rarity";
import { characterRarityGradientClass, rarityGradientClass } from "@/lib/catalog/rarity";
import { cn } from "@/lib/utils";
type CatalogItem = { key: string; name: string; imageUrl: string; rarity?: number | null };
@@ -113,6 +113,7 @@ export function GlossaryManager({
onValueChange={(key) => setItem(catalogs[kind].find((value) => value.key === key) ?? null)}
placeholder="ค้นหารายการ…"
rarityBackground
characterBackground={kind === "character"}
/>
</Field>
<Field>
@@ -154,7 +155,7 @@ export function GlossaryManager({
{catalogItem ? (
<span className={cn(
"relative size-10 shrink-0 overflow-hidden rounded-md bg-muted",
rarityGradientClass(catalogItem.rarity),
entry.kind === "character" ? characterRarityGradientClass(catalogItem.key, catalogItem.rarity) : rarityGradientClass(catalogItem.rarity),
)}>
<Image src={catalogItem.imageUrl} alt="" fill sizes="40px" className="object-contain" />
</span>
+3 -2
View File
@@ -162,7 +162,7 @@ import {
} from "@/lib/guides/stats";
import { elementBackgroundColor, elementIconFilter } from "@/lib/catalog/element";
import { supportsWeaponType } from "@/lib/catalog/lunaris";
import { rarityGradientClass } from "@/lib/catalog/rarity";
import { characterRarityGradientClass, rarityGradientClass } from "@/lib/catalog/rarity";
import { isCustomTravelerKey } from "@/lib/catalog/travelers";
import {
applyPresetFields,
@@ -3911,7 +3911,7 @@ function TeamEditor({
return (
<div key={member.characterKey} className="min-w-0 text-center">
<div className="flex items-center justify-center gap-2">
<div className={cn("relative size-16 shrink-0 overflow-hidden rounded-lg bg-muted", rarityGradientClass(isCustomTravelerKey(member.characterKey) ? 5 : character?.rarity))}>
<div className={cn("relative size-16 shrink-0 overflow-hidden rounded-lg bg-muted", characterRarityGradientClass(member.characterKey, isCustomTravelerKey(member.characterKey) ? 5 : character?.rarity))}>
{character ? <Image src={character.imageUrl} alt={character.name} fill sizes="64px" className="object-contain" /> : null}
</div>
<div className="flex flex-col gap-1">
@@ -4162,6 +4162,7 @@ function ExtraCatalogItemsEditor({
placeholder={`เลือก${labels[kind]}`}
showSelectedImage
rarityBackground
characterBackground={kind === "character"}
/>
</div>
</div>
+1
View File
@@ -219,6 +219,7 @@ function ItemPicker({
placeholder={`Search ${kind}…`}
emptyLabel="No matches"
rarityBackground
characterBackground={kind === "character"}
/>
</Field>
) : null}
+12 -7
View File
@@ -13,7 +13,7 @@ import {
ComboboxTrigger,
FuzzyCombobox,
} from "@/components/ui/combobox";
import { rarityGradientClass } from "@/lib/catalog/rarity";
import { characterRarityGradientClass, rarityGradientClass } from "@/lib/catalog/rarity";
import { cn } from "@/lib/utils";
export interface AdminCatalogItem {
@@ -50,6 +50,7 @@ type CommonSelectProps<Item extends AdminCatalogItem> = {
emptyLabel?: string;
invalid?: boolean;
rarityBackground?: boolean;
characterBackground?: boolean;
searchNames?: (item: Item) => string[];
};
@@ -69,6 +70,7 @@ export function CatalogDropdown<Item extends AdminCatalogItem>({
emptyLabel = "ไม่พบรายการ",
invalid = false,
rarityBackground = false,
characterBackground = false,
showSelectedImage = false,
showClear = true,
label,
@@ -82,7 +84,7 @@ export function CatalogDropdown<Item extends AdminCatalogItem>({
<div
className={cn(
"relative size-10 shrink-0 overflow-hidden rounded-md",
rarityBackground && rarityGradientClass(selected.rarity),
rarityBackground && (characterBackground ? characterRarityGradientClass(selected.key, selected.rarity) : rarityGradientClass(selected.rarity)),
)}
>
<Image src={selected.imageUrl} alt="" fill sizes="40px" className="object-contain" />
@@ -110,7 +112,7 @@ export function CatalogDropdown<Item extends AdminCatalogItem>({
<ComboboxList>
{(item) => (
<ComboboxItem key={item.key} value={item}>
<CatalogOptionImage item={item} rarityBackground={rarityBackground} />
<CatalogOptionImage item={item} rarityBackground={rarityBackground} characterBackground={characterBackground} />
<span className="whitespace-nowrap">{item.name}</span>
</ComboboxItem>
)}
@@ -138,6 +140,7 @@ function CatalogSlotSelect<Item extends AdminCatalogItem>({
emptyLabel = "ไม่พบรายการ",
invalid = false,
rarityBackground = true,
characterBackground = false,
searchNames = (item) => [item.name, ...(item.aliases ?? [])],
className,
}: CatalogSlotSelectProps<Item>) {
@@ -158,7 +161,7 @@ function CatalogSlotSelect<Item extends AdminCatalogItem>({
aria-invalid={invalid}
className={cn(
"relative flex aspect-square w-full items-center justify-center overflow-hidden rounded-md border bg-muted p-0 outline-none focus-visible:ring-2 focus-visible:ring-ring aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 [&>svg]:hidden",
rarityBackground && selected && rarityGradientClass(selected.rarity),
rarityBackground && selected && (characterBackground ? characterRarityGradientClass(selected.key, selected.rarity) : rarityGradientClass(selected.rarity)),
className,
)}
>
@@ -174,7 +177,7 @@ function CatalogSlotSelect<Item extends AdminCatalogItem>({
<ComboboxList>
{(item) => (
<ComboboxItem key={item.key} value={item}>
<CatalogOptionImage item={item} rarityBackground={rarityBackground} />
<CatalogOptionImage item={item} rarityBackground={rarityBackground} characterBackground={characterBackground} />
<span className="whitespace-nowrap">{item.name}</span>
</ComboboxItem>
)}
@@ -216,7 +219,7 @@ function DomainCatalogSelect<Item extends AdminCatalogItem>({
}
export function CharacterSelect<Item extends AdminCatalogItem>(props: DomainSelectProps<Item>) {
return <DomainCatalogSelect {...props} />;
return <DomainCatalogSelect {...props} characterBackground />;
}
export function WeaponSelect<Item extends AdminCatalogItem>(props: DomainSelectProps<Item>) {
@@ -318,15 +321,17 @@ export function ArtifactSelect<Item extends AdminCatalogItem>(
function CatalogOptionImage({
item,
rarityBackground,
characterBackground = false,
}: {
item: AdminCatalogItem;
rarityBackground: boolean;
characterBackground?: boolean;
}) {
return (
<div
className={cn(
"relative size-8 shrink-0 overflow-hidden rounded-md",
rarityBackground && rarityGradientClass(item.rarity),
rarityBackground && (characterBackground ? characterRarityGradientClass(item.key, item.rarity) : rarityGradientClass(item.rarity)),
)}
>
<Image src={item.imageUrl} alt="" fill sizes="32px" className="object-contain" />
+6 -6
View File
@@ -2,15 +2,15 @@ import Image from "next/image";
import { Badge } from "@/components/ui/badge";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { elementBackgroundColor } from "@/lib/catalog/element";
import { rarityGradientClass } from "@/lib/catalog/rarity";
import { characterRarityGradientClass, rarityGradientClass } from "@/lib/catalog/rarity";
import type { CommissionRequest } from "@/lib/commission/request";
import { cn } from "@/lib/utils";
type Item = { key: string; name: string; imageUrl: string; rarity?: number | null; element?: string | null };
type Catalog = { characters: Item[]; weapons: Item[]; artifacts: Item[] };
function ItemImage({ item, size = "small" }: { item: Item; size?: "small" | "large" }) {
return <div title={item.name} className={cn("relative aspect-square min-w-0 overflow-hidden rounded-lg", rarityGradientClass(item.rarity))}>
function ItemImage({ item, size = "small", character = false }: { item: Item; size?: "small" | "large"; character?: boolean }) {
return <div title={item.name} className={cn("relative aspect-square min-w-0 overflow-hidden rounded-lg", character ? characterRarityGradientClass(item.key, item.rarity) : rarityGradientClass(item.rarity))}>
<Image src={item.imageUrl} alt={item.name} fill sizes={size === "large" ? "160px" : "64px"} className="object-contain" />
</div>;
}
@@ -30,7 +30,7 @@ function CommissionTeamCard({ team, index, catalog }: { team: CommissionRequest[
const artifact = artifacts.get(member.artifactKey);
return <div key={memberIndex} className="min-w-0 rounded-lg p-1 lg:p-1.5" style={{ backgroundColor: elementBackgroundColor(character?.element) }}>
<div className="grid grid-cols-1 gap-1 lg:grid-cols-[2fr_1fr]">
{character ? <ItemImage item={character} size="large" /> : <div className="aspect-square rounded-lg bg-muted" />}
{character ? <ItemImage item={character} size="large" character /> : <div className="aspect-square rounded-lg bg-muted" />}
<div className="grid min-w-0 grid-cols-2 gap-0.5 lg:grid-cols-1 lg:grid-rows-2 lg:gap-1">
{weapon ? <ItemImage item={weapon} /> : <div title={member.weaponKey} className="aspect-square rounded-lg bg-muted" />}
{artifact ? <ItemImage item={artifact} /> : <div title={member.artifactKey} className="aspect-square rounded-lg bg-muted" />}
@@ -77,7 +77,7 @@ export function CommissionRequestSummary({ request, catalog, amountBaht }: {
: <p key={key} className="w-16 wrap-break-word text-xs">{key}</p>;
})}
</div>
{character ? <div className="w-16 min-w-0"><ItemImage item={character} size="large" /><p className="mt-1 truncate text-center text-xs" title={character.name}>{character.name}</p></div> : null}
{character ? <div className="w-16 min-w-0"><ItemImage item={character} size="large" character /><p className="mt-1 truncate text-center text-xs" title={character.name}>{character.name}</p></div> : null}
</CardContent>
</Card>;
})}
@@ -89,7 +89,7 @@ export function CommissionRequestSummary({ request, catalog, amountBaht }: {
</CardHeader>
<CardContent className="grid grid-cols-[minmax(0,1fr)_64px] items-center gap-3">
<div className="flex min-w-0 flex-wrap gap-2">{set.levels.map((level) => <Badge key={level} variant="outline">C{level}</Badge>)}</div>
{character ? <div className="w-16 min-w-0"><ItemImage item={character} size="large" /><p className="mt-1 truncate text-center text-xs" title={character.name}>{character.name}</p></div> : null}
{character ? <div className="w-16 min-w-0"><ItemImage item={character} size="large" character /><p className="mt-1 truncate text-center text-xs" title={character.name}>{character.name}</p></div> : null}
</CardContent>
</Card>;
})}
+17 -18
View File
@@ -776,8 +776,24 @@ export function CommissionTicketChat({
mine ? "items-end" : "items-start",
)}
>
<div
className={cn(
"w-full px-1 text-center text-xs font-medium text-muted-foreground",
mine ? "translate-x-5" : "-translate-x-5",
)}
>
<time
dateTime={sentAt.toISOString()}
title={sentAt.toLocaleString("th-TH")}
>
{sentAt.toLocaleTimeString("th-TH", {
hour: "2-digit",
minute: "2-digit",
})}
</time>
</div>
<MessageHeader className="px-1">
{mine ? "คุณ" : message.authorName}
{message.authorName}
</MessageHeader>
<div
className={cn(
@@ -947,22 +963,6 @@ export function CommissionTicketChat({
))}
</div>
)}
<MessageFooter
className={cn(
"w-full justify-center gap-1 px-1 group-data-[align=end]/message:justify-center",
mine ? "translate-x-5" : "-translate-x-5",
)}
>
<time
dateTime={sentAt.toISOString()}
title={sentAt.toLocaleString("th-TH")}
>
{sentAt.toLocaleTimeString("th-TH", {
hour: "2-digit",
minute: "2-digit",
})}
</time>
</MessageFooter>
</MessageContent>
</Message>
);
@@ -970,7 +970,6 @@ export function CommissionTicketChat({
{visibleOptimisticMessages.map((message) => (
<Message key={message.localId} align="end">
<MessageContent className="w-full items-end gap-1">
<MessageHeader className="px-1">คุณ</MessageHeader>
<Bubble
variant={message.imageUrl ? "ghost" : "muted"}
className="max-w-[min(82%,36rem)]"
+1 -1
View File
@@ -21,7 +21,7 @@ export async function CommissionTicketDetail({ id, admin }: { id: string; admin:
const catalog = await getCommissionLabels(data.checkout.request);
return <div className="flex min-h-0 flex-1 flex-col gap-3">
<CommissionTicketPanels summary={
<Card className="h-full min-h-0"><CardHeader className="shrink-0"><CardTitle>คำขอที่ชำระเงินแล้ว - ฿{data.checkout.amountBaht}</CardTitle></CardHeader>
<Card className="h-full min-h-0"><CardHeader className="shrink-0"><CardTitle>รายละเอียดคำขอ - ฿{data.checkout.amountBaht}</CardTitle></CardHeader>
<CardContent className="flex min-h-0 flex-1 flex-col gap-3 overflow-y-auto">{catalog && <CommissionRequestSummary request={data.checkout.request} catalog={catalog} amountBaht={data.checkout.amountBaht} />}
<p className="text-sm text-muted-foreground">การชำระเงิน: {data.payment.transRef} - {data.payment.transferredAt.toLocaleString("th-TH")}</p>
<CommissionSlipDialog src={publicMediaUrl(data.payment.slipObjectKey)} />
+2 -2
View File
@@ -7,7 +7,7 @@ import {
StygianBossTab,
} from "@/components/stygian/stygian-boss-display";
import { elementIconFilter } from "@/lib/catalog/element";
import { rarityGradientClass } from "@/lib/catalog/rarity";
import { characterRarityGradientClass, rarityGradientClass } from "@/lib/catalog/rarity";
import type { getActiveCatalog } from "@/lib/guides/queries";
import type { getStygianSchedule } from "@/lib/stygian/repository";
import { cn } from "@/lib/utils";
@@ -47,7 +47,7 @@ function RecommendationIcon({ item, catalog, teamLayout = false }: { item: Item;
return (
<div className={cn("flex min-w-0 flex-col gap-1 rounded-lg border bg-card p-1", teamLayout && "w-full sm:p-2", teamLayout && hasEquipment && "sm:w-[164px]", teamLayout && !hasEquipment && "sm:w-[116px]", teamLayout && !hasEquipment && item.constellationLevel === null && "aspect-square justify-center")}>
<div className={teamLayout && hasEquipment ? "flex flex-col gap-1 sm:grid sm:grid-cols-[100px_40px] sm:gap-2" : "flex flex-col gap-1"}>
<div className={cn("relative aspect-square overflow-hidden rounded-lg", teamLayout && "sm:size-[100px]", teamLayout && hasEquipment && "sm:row-span-2", rarityGradientClass(value.rarity))}>
<div className={cn("relative aspect-square overflow-hidden rounded-lg", teamLayout && "sm:size-[100px]", teamLayout && hasEquipment && "sm:row-span-2", characterRarityGradientClass(item.catalogKey, value.rarity))}>
{value.imageUrl ? <Image src={value.imageUrl} alt={value.name} fill sizes={teamLayout ? "(min-width: 640px) 128px, 25vw" : "128px"} className="object-contain" /> : null}
</div>
{hasEquipment ? <div className={teamLayout ? "grid grid-cols-2 gap-1 sm:row-span-2 sm:grid-cols-1 sm:gap-2 sm:self-center" : "grid grid-cols-2 gap-1"}>
+4 -3
View File
@@ -25,7 +25,7 @@ import {
import { Separator } from "@/components/ui/separator";
import { ToggleGroup, ToggleGroupItem } from "@/components/ui/toggle-group";
import { elementBackgroundColor } from "@/lib/catalog/element";
import { rarityGradientClass } from "@/lib/catalog/rarity";
import { characterRarityGradientClass, rarityGradientClass } from "@/lib/catalog/rarity";
import { isCustomTravelerKey } from "@/lib/catalog/travelers";
import type { PublicGuide } from "@/lib/guides/queries";
import { teamConstellationLabel, teamRefinementLabel } from "@/lib/guides/team-tools";
@@ -226,7 +226,7 @@ export function TeamExportImage({ team }: { team: TeamExportData }) {
const percent = total > 0 ? damage / total * 100 : 0;
return (
<div key={member.position} className="flex h-43.5 items-center gap-6 rounded-3xl p-3.5" style={{ backgroundColor: elementBackgroundColor(member.character.element) }}>
<div className={cn("relative size-35 shrink-0 overflow-hidden rounded-3xl border-[3px] border-white/20", rarityGradientClass(isCustomTravelerKey(member.character.key) ? 5 : member.character.rarity))}>
<div className={cn("relative size-35 shrink-0 overflow-hidden rounded-3xl border-[3px] border-white/20", characterRarityGradientClass(member.character.key, isCustomTravelerKey(member.character.key) ? 5 : member.character.rarity))}>
<Image src={member.character.imageUrl} alt="" fill loading="eager" sizes="140px" className="object-contain" />
</div>
<div className="grid w-44 shrink-0 grid-cols-2 gap-3">
@@ -316,7 +316,8 @@ function TeamCard({
exporting
? "col-span-2 row-span-2"
: "sm:col-span-2 sm:row-span-2",
rarityGradientClass(
characterRarityGradientClass(
member.character.key,
isCustomTravelerKey(member.character.key)
? 5
: member.character.rarity,
+15 -3
View File
@@ -1,11 +1,13 @@
import { describe, expect, it } from "vitest";
import { rarityGradient, rarityGradientClass, rarityTextClass, rarityTextColor } from "@/lib/catalog/rarity";
import { characterRarityGradientClass, rarityGradient, rarityGradientClass, rarityTextClass, rarityTextColor } from "@/lib/catalog/rarity";
describe("catalog rarity backgrounds", () => {
it("maps every weapon and artifact rarity to its Tailwind gradient", () => {
expect(rarityGradientClass(1)).toContain("rgba(23,25,28,1)");
expect(rarityGradientClass(2)).toContain("rgba(11,43,24,1)");
expect(rarityGradientClass(1)).toBe("bg-[#697177] bg-[linear-gradient(90deg,rgba(105,113,119,1)_0%,rgba(137,144,147,1)_100%)]");
expect(rarityGradientClass(2)).toBe("bg-[#5D8972] bg-[linear-gradient(90deg,rgba(93,137,114,1)_0%,rgba(121,167,127,1)_100%)]");
expect(rarityGradient(1)).toBe("linear-gradient(90deg, rgba(105, 113, 119, 1) 0%, rgba(137, 144, 147, 1) 100%)");
expect(rarityGradient(2)).toBe("linear-gradient(90deg, rgba(93, 137, 114, 1) 0%, rgba(121, 167, 127, 1) 100%)");
expect(rarityGradientClass(3)).toBe("bg-[#4D7691] bg-[linear-gradient(90deg,rgba(77,118,145,1)_0%,rgba(71,135,165,1)_100%)]");
expect(rarityGradientClass(4)).toBe("bg-[#6D6A9C] bg-[linear-gradient(90deg,rgba(109,106,156,1)_0%,rgba(150,122,179,1)_100%)]");
expect(rarityGradientClass(5)).toBe("bg-[#A67B34] bg-[linear-gradient(90deg,rgba(166,123,52,1)_0%,rgba(178,123,44,1)_100%)]");
@@ -26,4 +28,14 @@ describe("catalog rarity backgrounds", () => {
expect(rarityTextClass(undefined)).toBeUndefined();
expect(rarityTextColor(undefined)).toBe("#17171c");
});
it("uses red for special characters without changing other rarity backgrounds", () => {
for (const key of ["10000062", "10000117", "10000118"]) {
expect(characterRarityGradientClass(key, 5)).toBe("bg-[#9A424E] bg-[linear-gradient(90deg,#9A424E_0%,#B85D67_100%)]");
expect(characterRarityGradientClass(key, null)).toBe(characterRarityGradientClass(key, 5));
}
expect(characterRarityGradientClass("ordinary-character", 5)).toBe(rarityGradientClass(5));
expect(characterRarityGradientClass("ordinary-character", 1)).toBe(rarityGradientClass(1));
expect(characterRarityGradientClass("ordinary-character", 2)).toBe(rarityGradientClass(2));
});
});
+11 -4
View File
@@ -1,14 +1,17 @@
const rarityGradientClasses: Record<number, string> = {
1: "bg-[linear-gradient(90deg,rgba(23,25,28,1)_0%,rgba(19,20,23,1)_100%)]",
2: "bg-[linear-gradient(90deg,rgba(11,43,24,1)_0%,rgba(7,18,13,1)_100%)]",
1: "bg-[#697177] bg-[linear-gradient(90deg,rgba(105,113,119,1)_0%,rgba(137,144,147,1)_100%)]",
2: "bg-[#5D8972] bg-[linear-gradient(90deg,rgba(93,137,114,1)_0%,rgba(121,167,127,1)_100%)]",
3: "bg-[#4D7691] bg-[linear-gradient(90deg,rgba(77,118,145,1)_0%,rgba(71,135,165,1)_100%)]",
4: "bg-[#6D6A9C] bg-[linear-gradient(90deg,rgba(109,106,156,1)_0%,rgba(150,122,179,1)_100%)]",
5: "bg-[#A67B34] bg-[linear-gradient(90deg,rgba(166,123,52,1)_0%,rgba(178,123,44,1)_100%)]",
};
const specialCharacterKeys = new Set(["10000062", "10000117", "10000118"]);
const specialCharacterGradientClass = "bg-[#9A424E] bg-[linear-gradient(90deg,#9A424E_0%,#B85D67_100%)]";
const rarityGradients: Record<number, string> = {
1: "linear-gradient(90deg, rgba(23, 25, 28, 1) 0%, rgba(19, 20, 23, 1) 100%)",
2: "linear-gradient(90deg, rgba(11, 43, 24, 1) 0%, rgba(7, 18, 13, 1) 100%)",
1: "linear-gradient(90deg, rgba(105, 113, 119, 1) 0%, rgba(137, 144, 147, 1) 100%)",
2: "linear-gradient(90deg, rgba(93, 137, 114, 1) 0%, rgba(121, 167, 127, 1) 100%)",
3: "linear-gradient(90deg, rgba(77, 118, 145, 1) 0%, rgba(71, 135, 165, 1) 100%)",
4: "linear-gradient(90deg, rgba(109, 106, 156, 1) 0%, rgba(150, 122, 179, 1) 100%)",
5: "linear-gradient(90deg, rgba(166, 123, 52, 1) 0%, rgba(178, 123, 44, 1) 100%)",
@@ -30,6 +33,10 @@ export function rarityGradientClass(rarity: number | null | undefined): string |
return rarity ? rarityGradientClasses[rarity] : undefined;
}
export function characterRarityGradientClass(key: string | null | undefined, rarity: number | null | undefined): string | undefined {
return key && specialCharacterKeys.has(key) ? specialCharacterGradientClass : rarityGradientClass(rarity);
}
export function rarityGradient(rarity: number | null | undefined): string {
return (rarity && rarityGradients[rarity]) || "#17383d";
}
+1
View File
@@ -182,6 +182,7 @@ function rarity(value: string | undefined): number | null {
QUALITY_BLUE: 3,
QUALITY_PURPLE: 4,
QUALITY_ORANGE: 5,
QUALITY_ORANGE_SP: 5,
}[value] ?? null
);
}
+1 -1
View File
@@ -1,7 +1,7 @@
import * as z from "zod";
export const lunarisVersionSchema = z.string().regex(/^\d+(?:\.\d+)+$/u);
export const catalogFormatVersion = 2;
export const catalogFormatVersion = 3;
export interface LunarisVersionChange {
previousVersion: string;