fix ja language, instead fetch by axios
This commit is contained in:
@@ -9,6 +9,7 @@ import { useTranslations } from "next-intl";
|
||||
import { motion } from "framer-motion";
|
||||
import { getNameChar } from "@/helper";
|
||||
import Image from "next/image";
|
||||
import NameAvatar from "../nameAvatar";
|
||||
|
||||
export default function ActionBar() {
|
||||
const [selectTurn, setSelectTurn] = useState<SkillBattleInfo | null>(null);
|
||||
@@ -128,8 +129,11 @@ export default function ActionBar() {
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="text-base-content text-center text-sm mt-1 font-medium">{getNameChar(locale, data)}</div>
|
||||
<NameAvatar
|
||||
locale={locale}
|
||||
text={getNameChar(locale, data)}
|
||||
className="text-base-content text-center text-sm mt-1 font-medium"
|
||||
/>
|
||||
</div>
|
||||
<div className="grid grid-cols-1 justify-center gap-2 py-2 w-full">
|
||||
<div className="bg-local text-primary text-xs max-w-full">
|
||||
@@ -180,14 +184,18 @@ export default function ActionBar() {
|
||||
<h4 className="text-lg font-semibold mb-2 text-pink-500">{transI18n("characterInformation")}</h4>
|
||||
<div className="grid grid-cols-1 sm:grid-cols-2 gap-4 items-center">
|
||||
<div className="flex flex-col space-y-2">
|
||||
<p className="flex items-center gap-2">
|
||||
<div className="flex items-center gap-2">
|
||||
<span className="font-medium text-base-content/70">{transI18n("id")}:</span>
|
||||
<span className="font-bold">{selectAvatar.id}</span>
|
||||
</p>
|
||||
<p className="flex items-center gap-2">
|
||||
</div>
|
||||
<div className="flex items-center gap-2">
|
||||
<span className="font-medium text-base-content/70">{transI18n("character")}:</span>
|
||||
<span className="font-bold">{getNameChar(locale, selectAvatar)}</span>
|
||||
</p>
|
||||
<NameAvatar
|
||||
locale={locale}
|
||||
text={getNameChar(locale, selectAvatar)}
|
||||
className="font-bold"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex justify-center items-center">
|
||||
<Image
|
||||
|
||||
@@ -3,16 +3,12 @@
|
||||
import { getNameChar } from '@/helper';
|
||||
import useLocaleStore from '@/stores/localeStore';
|
||||
import { AvatarHakushiType } from '@/types';
|
||||
import NameAvatar from '../nameAvatar';
|
||||
|
||||
interface CharacterCardProps {
|
||||
data: AvatarHakushiType
|
||||
}
|
||||
|
||||
export function parseRuby(text: string): string {
|
||||
return text.replace(/\{RUBY_B#(.*?)\}(.*?)\{RUBY_E#\}/g, (_, furigana, kanji) => {
|
||||
return `<ruby>${kanji}<rt>${furigana}</rt></ruby>`;
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
export default function CharacterCard({ data }: CharacterCardProps) {
|
||||
@@ -20,47 +16,41 @@ export default function CharacterCard({ data }: CharacterCardProps) {
|
||||
const text = getNameChar(locale, data)
|
||||
return (
|
||||
<li className="z-10 flex flex-col w-28 items-center p-1 rounded-md shadow-lg bg-gradient-to-b from-customStart to-customEnd transform transition-transform duration-300 hover:scale-105 m-1">
|
||||
<div
|
||||
className={`w-[80px] rounded-md p-[2px] bg-gradient-to-br ${
|
||||
data.rank === "CombatPowerAvatarRarityType5"
|
||||
? "from-yellow-400 via-yellow-300 to-yellow-500"
|
||||
: "from-purple-300 via-purple-200 to-purple-400"
|
||||
}`}
|
||||
>
|
||||
|
||||
<div className="relative w-full h-full">
|
||||
<img
|
||||
loading="lazy"
|
||||
src={`https://api.hakush.in/hsr/UI/avatarshopicon/${data.id}.webp`}
|
||||
className="w-full h-full rounded-md object-cover"
|
||||
alt="ALT"
|
||||
/>
|
||||
<img
|
||||
loading='lazy'
|
||||
src={`https://api.hakush.in/hsr/UI/element/${data.damageType.toLowerCase()}.webp`}
|
||||
className="absolute top-0 left-0 w-6 h-6"
|
||||
alt={data.damageType.toLowerCase()}
|
||||
/>
|
||||
<img
|
||||
loading='lazy'
|
||||
src={`https://api.hakush.in/hsr/UI/pathicon/${data.baseType.toLowerCase()}.webp`}
|
||||
className="absolute top-0 right-0 w-6 h-6"
|
||||
alt={data.baseType.toLowerCase()}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{locale === "jp" ? (
|
||||
<div
|
||||
className="mt-2 text-center text-base font-normal leading-tight"
|
||||
dangerouslySetInnerHTML={{ __html: parseRuby(text) }}
|
||||
/>
|
||||
) : (
|
||||
<div className="mt-2 text-center text-base font-normal leading-tight">
|
||||
{text}
|
||||
className={`w-[80px] rounded-md p-[2px] bg-gradient-to-br ${data.rank === "CombatPowerAvatarRarityType5"
|
||||
? "from-yellow-400 via-yellow-300 to-yellow-500"
|
||||
: "from-purple-300 via-purple-200 to-purple-400"
|
||||
}`}
|
||||
>
|
||||
|
||||
<div className="relative w-full h-full">
|
||||
<img
|
||||
loading="lazy"
|
||||
src={`https://api.hakush.in/hsr/UI/avatarshopicon/${data.id}.webp`}
|
||||
className="w-full h-full rounded-md object-cover"
|
||||
alt="ALT"
|
||||
/>
|
||||
<img
|
||||
loading='lazy'
|
||||
src={`https://api.hakush.in/hsr/UI/element/${data.damageType.toLowerCase()}.webp`}
|
||||
className="absolute top-0 left-0 w-6 h-6"
|
||||
alt={data.damageType.toLowerCase()}
|
||||
/>
|
||||
<img
|
||||
loading='lazy'
|
||||
src={`https://api.hakush.in/hsr/UI/pathicon/${data.baseType.toLowerCase()}.webp`}
|
||||
className="absolute top-0 right-0 w-6 h-6"
|
||||
alt={data.baseType.toLowerCase()}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</li>
|
||||
|
||||
<NameAvatar
|
||||
locale={locale}
|
||||
text={text}
|
||||
className="mt-2 text-center text-base font-normal leading-tight"
|
||||
/>
|
||||
</li>
|
||||
|
||||
);
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@ export default function Header() {
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
console.log(navigator.language.slice(0, 2))
|
||||
|
||||
const cookieLocale = document.cookie.split("; ")
|
||||
.find((row) => row.startsWith("MYNEXTAPP_LOCALE"))
|
||||
?.split("=")[1];
|
||||
|
||||
@@ -14,10 +14,11 @@ import { DamageLineForOne } from "../chart/damageLineForOne";
|
||||
import { DamagePerCycleForOne } from "../chart/damagePerCycleForOne";
|
||||
import { useCalcTotalDmgAvatar, useCalcTotalTurnAvatar } from "@/hooks/useCalcAvatarData";
|
||||
import Image from "next/image";
|
||||
import NameAvatar from "../nameAvatar";
|
||||
// import ShowCaseInfo from "../card/showCaseCard";
|
||||
|
||||
export default function LineupBar() {
|
||||
const [selectedCharacter, setSelectedCharacter] = useState<AvatarHakushiType | null>(null);
|
||||
const [selectedCharacter, setSelectedCharacter] = useState<AvatarHakushiType | undefined>(undefined);
|
||||
const [isModalOpen, setIsModalOpen] = useState(false);
|
||||
|
||||
const transI18n = useTranslations("DataAnalysisPage");
|
||||
@@ -44,7 +45,7 @@ export default function LineupBar() {
|
||||
// Close modal handler
|
||||
const handleCloseModal = (modalId: string) => {
|
||||
setIsModalOpen(false);
|
||||
setSelectedCharacter(null);
|
||||
setSelectedCharacter(undefined);
|
||||
const modal = document.getElementById(modalId) as HTMLDialogElement | null;
|
||||
if (modal) {
|
||||
modal.close()
|
||||
@@ -80,7 +81,16 @@ export default function LineupBar() {
|
||||
<path strokeLinecap="round" strokeLinejoin="round" d="M17.982 18.725A7.488 7.488 0 0 0 12 15.75a7.488 7.488 0 0 0-5.982 2.975m11.963 0a9 9 0 1 0-11.963 0m11.963 0A8.966 8.966 0 0 1 12 21a8.966 8.966 0 0 1-5.982-2.275M15 9.75a3 3 0 1 1-6 0 3 3 0 0 1 6 0Z" />
|
||||
</svg>
|
||||
|
||||
<span className="text-sm truncate">{transI18n("lastTurn")}: {getNameChar(locale, listAvatar.find(it => it.id === turnHistory.findLast(i => i?.avatarId)?.avatarId?.toString()))}</span>
|
||||
<span className="text-sm truncate flex flex-row">
|
||||
<div>
|
||||
{transI18n("lastTurn")}:
|
||||
</div>
|
||||
|
||||
<NameAvatar
|
||||
locale={locale}
|
||||
text={getNameChar(locale, listAvatar.find(it => it.id === turnHistory.findLast(i => i?.avatarId)?.avatarId?.toString()))}
|
||||
/>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -132,9 +142,12 @@ export default function LineupBar() {
|
||||
</div>
|
||||
|
||||
<div className="border-b border-purple-500/30 px-6 py-4 mb-4">
|
||||
<h3 className="font-bold text-2xl text-transparent bg-clip-text bg-gradient-to-r from-pink-400 to-cyan-400">
|
||||
{selectedCharacter ? getNameChar(locale, selectedCharacter).toUpperCase() : ""}
|
||||
</h3>
|
||||
|
||||
<NameAvatar
|
||||
locale={locale}
|
||||
text={getNameChar(locale, selectedCharacter).toUpperCase()}
|
||||
className={"font-bold text-2xl text-transparent bg-clip-text bg-gradient-to-r from-pink-400 to-cyan-400"}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{selectedCharacter && (
|
||||
|
||||
16
src/components/nameAvatar/index.tsx
Normal file
16
src/components/nameAvatar/index.tsx
Normal file
@@ -0,0 +1,16 @@
|
||||
import { parseRuby } from "@/helper";
|
||||
|
||||
|
||||
|
||||
interface TextProps {
|
||||
text: string;
|
||||
locale: string;
|
||||
className?: string;
|
||||
}
|
||||
|
||||
export default function NameAvatar({ text, locale, className }: TextProps) {
|
||||
if (locale === "ja") {
|
||||
return <div className={className} dangerouslySetInnerHTML={{ __html: parseRuby(text) }} />;
|
||||
}
|
||||
return <div className={className}>{text}</div>;
|
||||
}
|
||||
@@ -12,13 +12,19 @@ export function getNameChar(locale: string, data: AvatarHakushiType | undefined)
|
||||
|
||||
let text = data.lang.get(listCurrentLanguage[locale as keyof typeof listCurrentLanguage].toLowerCase()) ?? "";
|
||||
if (!text) {
|
||||
text = data.lang.get("en") ?? "";
|
||||
text = data.lang.get("en") ?? "";
|
||||
}
|
||||
if (Number(data.id) % 2 === 0 && Number(data.id) > 8000) {
|
||||
text = `Female ${data.damageType} MC`
|
||||
text = `Female ${data.damageType} MC`
|
||||
} else if (Number(data.id) > 8000) {
|
||||
text = `Male ${data.damageType} MC`
|
||||
text = `Male ${data.damageType} MC`
|
||||
}
|
||||
|
||||
return text
|
||||
}
|
||||
|
||||
export function parseRuby(text: string): string {
|
||||
const rubyRegex = /\{RUBY_B#(.*?)\}(.*?)\{RUBY_E#\}/gs;
|
||||
return text.replace(rubyRegex, (_match, furigana, kanji) => {
|
||||
return `<ruby>${kanji}<rt>${furigana}</rt></ruby>`;
|
||||
});
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
import useSocketStore from "@/stores/socketSettingStore";
|
||||
import { AvatarHakushiType, AvatarHakushiRawType } from "@/types/avatar";
|
||||
|
||||
import axios from 'axios';
|
||||
|
||||
export async function checkConnectTcpApi(): Promise<boolean> {
|
||||
const { host, port, connectionType } = useSocketStore.getState()
|
||||
@@ -23,22 +23,27 @@ export async function checkConnectTcpApi(): Promise<boolean> {
|
||||
}
|
||||
|
||||
export async function getCharacterListApi(): Promise<AvatarHakushiType[]> {
|
||||
const res = await fetch('/api/hakushin', {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
});
|
||||
try {
|
||||
const res = await axios.get<Record<string, AvatarHakushiRawType>>(
|
||||
'https://api.hakush.in/hsr/data/character.json',
|
||||
{
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
if (!res.ok) {
|
||||
console.log(`Error ${res.status}: ${res.statusText}`);
|
||||
const data = new Map(Object.entries(res.data));
|
||||
|
||||
return Array.from(data.entries()).map(([id, it]) => convertAvatar(id, it));
|
||||
} catch (error: unknown) {
|
||||
if (axios.isAxiosError(error)) {
|
||||
console.log(`Error: ${error.response?.status} - ${error.message}`);
|
||||
} else {
|
||||
console.log(`Unexpected error: ${String(error)}`);
|
||||
}
|
||||
return [];
|
||||
}
|
||||
|
||||
const data: Map<string, AvatarHakushiRawType> = new Map(Object.entries(await res.json()));
|
||||
|
||||
|
||||
return Array.from(data.entries()).map(([id, it]) => convertAvatar(id, it));
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user