Refactor elfs data
This commit is contained in:
@@ -1,22 +1,16 @@
|
|||||||
/** @jsxImportSource theme-ui */
|
/** @jsxImportSource theme-ui */
|
||||||
|
|
||||||
import { Box, Card, Text } from '@theme-ui/components'
|
import { Box, Card, Text } from '@theme-ui/components'
|
||||||
import { useRouter } from 'next/router'
|
|
||||||
import { assetsBucketBaseUrl } from '../../lib/consts'
|
import { assetsBucketBaseUrl } from '../../lib/consts'
|
||||||
import { ElfData } from '../../lib/honkai3rd/elfs'
|
import { ElfData } from '../../lib/honkai3rd/elfs'
|
||||||
import { translate } from '../../lib/i18n'
|
|
||||||
import PageLink from '../atoms/PageLink'
|
import PageLink from '../atoms/PageLink'
|
||||||
import SquareImageBox from '../atoms/SquareImageBox'
|
import SquareImageBox from '../atoms/SquareImageBox'
|
||||||
|
|
||||||
interface ElfCardProps {
|
interface ElfCardProps {
|
||||||
elf: Pick<ElfData, 'id' | 'name' | 'krName'>
|
elf: Pick<ElfData, 'id' | 'name'>
|
||||||
hidden?: boolean
|
hidden?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
const ElfCard = ({ elf }: ElfCardProps) => {
|
const ElfCard = ({ elf }: ElfCardProps) => {
|
||||||
const { locale } = useRouter()
|
|
||||||
const elfName = translate(locale, { 'ko-KR': elf.krName }, elf.name)
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Card
|
<Card
|
||||||
sx={{
|
sx={{
|
||||||
@@ -30,7 +24,7 @@ const ElfCard = ({ elf }: ElfCardProps) => {
|
|||||||
>
|
>
|
||||||
<PageLink href={`/honkai3rd/elfs/${elf.id}`}>
|
<PageLink href={`/honkai3rd/elfs/${elf.id}`}>
|
||||||
<SquareImageBox
|
<SquareImageBox
|
||||||
alt={elfName}
|
alt={elf.name}
|
||||||
src={`${assetsBucketBaseUrl}/honkai3rd/elfs/icon-${elf.id}.png`}
|
src={`${assetsBucketBaseUrl}/honkai3rd/elfs/icon-${elf.id}.png`}
|
||||||
size={[100]}
|
size={[100]}
|
||||||
/>
|
/>
|
||||||
@@ -43,7 +37,7 @@ const ElfCard = ({ elf }: ElfCardProps) => {
|
|||||||
textAlign: 'center',
|
textAlign: 'center',
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Text>{elfName}</Text>
|
<Text>{elf.name}</Text>
|
||||||
</Box>
|
</Box>
|
||||||
</PageLink>
|
</PageLink>
|
||||||
</Card>
|
</Card>
|
||||||
|
|||||||
@@ -1,16 +1,13 @@
|
|||||||
export interface ElfSkill {
|
export interface ElfSkill {
|
||||||
type: 'passive' | 'basic' | 'ultimate' | 'team'
|
type: 'passive' | 'basic' | 'ultimate' | 'team'
|
||||||
name: string
|
name: string
|
||||||
krName?: string
|
|
||||||
requiredRank: number
|
requiredRank: number
|
||||||
description: string
|
description: string
|
||||||
krDescription?: string
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ElfData {
|
export interface ElfData {
|
||||||
id: string
|
id: string
|
||||||
name: string
|
name: string
|
||||||
krName?: string
|
|
||||||
baseRank: number
|
baseRank: number
|
||||||
features: string[]
|
features: string[]
|
||||||
skillRows: [ElfSkill[], ElfSkill[], ElfSkill[], ElfSkill[]]
|
skillRows: [ElfSkill[], ElfSkill[], ElfSkill[], ElfSkill[]]
|
||||||
|
|||||||
@@ -30,12 +30,10 @@ const ElfShowPage = ({ elf }: ElfShowPageProps) => {
|
|||||||
const { locale } = useRouter()
|
const { locale } = useRouter()
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
|
|
||||||
const elfName = translate(locale, { 'ko-KR': elf.krName }, elf.name)
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Honkai3rdLayout>
|
<Honkai3rdLayout>
|
||||||
<Head
|
<Head
|
||||||
title={`${t('common.honkai-3rd')}: ${elfName} - ${t(
|
title={`${t('common.honkai-3rd')}: ${elf.name} - ${t(
|
||||||
'common.abyss-lab'
|
'common.abyss-lab'
|
||||||
)}`}
|
)}`}
|
||||||
description={`${t('common.honkai-3rd')} ${t(
|
description={`${t('common.honkai-3rd')} ${t(
|
||||||
@@ -63,12 +61,12 @@ const ElfShowPage = ({ elf }: ElfShowPageProps) => {
|
|||||||
{ href: '/honkai3rd/elfs', label: t('common.elfs') },
|
{ href: '/honkai3rd/elfs', label: t('common.elfs') },
|
||||||
{
|
{
|
||||||
href: `/honkai3rd/elfs/${elf.id}`,
|
href: `/honkai3rd/elfs/${elf.id}`,
|
||||||
label: elfName,
|
label: elf.name,
|
||||||
},
|
},
|
||||||
]}
|
]}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Heading as='h1'>{elfName}</Heading>
|
<Heading as='h1'>{elf.name}</Heading>
|
||||||
|
|
||||||
<Box mb={3}>
|
<Box mb={3}>
|
||||||
<Box
|
<Box
|
||||||
@@ -111,7 +109,7 @@ const ElfShowPage = ({ elf }: ElfShowPageProps) => {
|
|||||||
as={columnIndex === 0 ? 'h2' : 'h3'}
|
as={columnIndex === 0 ? 'h2' : 'h3'}
|
||||||
sx={{ mb: 1 }}
|
sx={{ mb: 1 }}
|
||||||
>
|
>
|
||||||
{translate(locale, { 'ko-KR': item.krName }, item.name)}
|
{item.name}
|
||||||
</Heading>
|
</Heading>
|
||||||
<SecondaryLabel>
|
<SecondaryLabel>
|
||||||
{t(`elfs-show.${item.type}`)}
|
{t(`elfs-show.${item.type}`)}
|
||||||
@@ -125,11 +123,7 @@ const ElfShowPage = ({ elf }: ElfShowPageProps) => {
|
|||||||
whiteSpace: 'pre-wrap',
|
whiteSpace: 'pre-wrap',
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{translate(
|
{item.description}
|
||||||
locale,
|
|
||||||
{ 'ko-KR': item.krDescription },
|
|
||||||
item.description
|
|
||||||
)}
|
|
||||||
</Paragraph>
|
</Paragraph>
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
)
|
)
|
||||||
@@ -148,7 +142,7 @@ export async function getStaticProps({
|
|||||||
params,
|
params,
|
||||||
locale,
|
locale,
|
||||||
}: NextPageContext & { params: { elfId: string } }) {
|
}: NextPageContext & { params: { elfId: string } }) {
|
||||||
const elf = getElfById(params.elfId)
|
const elf = getElfById(params.elfId, locale)
|
||||||
return {
|
return {
|
||||||
props: { elf, ...(await getI18NProps(locale)) },
|
props: { elf, ...(await getI18NProps(locale)) },
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ import Head from '../../../components/atoms/Head'
|
|||||||
import Honkai3rdLayout from '../../../components/layouts/Honkai3rdLayout'
|
import Honkai3rdLayout from '../../../components/layouts/Honkai3rdLayout'
|
||||||
|
|
||||||
interface ElfListPageProps {
|
interface ElfListPageProps {
|
||||||
elfs: Pick<ElfData, 'id' | 'name' | 'krName'>[]
|
elfs: Pick<ElfData, 'id' | 'name'>[]
|
||||||
}
|
}
|
||||||
|
|
||||||
const ElfListPage = ({ elfs }: ElfListPageProps) => {
|
const ElfListPage = ({ elfs }: ElfListPageProps) => {
|
||||||
@@ -56,7 +56,7 @@ export default ElfListPage
|
|||||||
export async function getStaticProps({ locale }: NextPageContext) {
|
export async function getStaticProps({ locale }: NextPageContext) {
|
||||||
return {
|
return {
|
||||||
props: {
|
props: {
|
||||||
elfs: listElfs().map((elf) => pick(['id', 'name', 'krName'], elf)),
|
elfs: listElfs(locale).map((elf) => pick(['id', 'name', 'krName'], elf)),
|
||||||
...(await getI18NProps(locale)),
|
...(await getI18NProps(locale)),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,82 +1,56 @@
|
|||||||
import { readdirSync, readFileSync, readJsonFileSync } from '../fs'
|
|
||||||
import { compareVersion } from '../../../lib/string'
|
import { compareVersion } from '../../../lib/string'
|
||||||
import { ElfData } from '../../../lib/honkai3rd/elfs'
|
import { ElfData } from '../../../lib/honkai3rd/elfs'
|
||||||
|
import yaml from 'yaml'
|
||||||
|
import fs from 'fs'
|
||||||
|
import path from 'path'
|
||||||
|
import { omit } from 'ramda'
|
||||||
|
|
||||||
const elfFileNameList = readdirSync('honkai3rd/elfs')
|
let cachedData: any = null
|
||||||
const elfDataList = elfFileNameList
|
|
||||||
.map((fileName) => {
|
|
||||||
const filePathname = 'honkai3rd/elfs/' + fileName
|
|
||||||
const data = readJsonFileSync(filePathname) as ElfData
|
|
||||||
|
|
||||||
const krDataFilePath = `honkai3rd/ko-KR/elfs/${data.id}.md`
|
export function listElfs(locale?: string): ElfData[] {
|
||||||
try {
|
if (cachedData == null) {
|
||||||
const krData = parseElfData(readFileSync(krDataFilePath).toString())
|
cachedData = yaml.parse(
|
||||||
data.krName = krData.name
|
fs
|
||||||
data.skillRows.forEach((skillRow, skillRowIndex) => {
|
.readFileSync(path.join(process.cwd(), 'data/honkai3rd/elfs.yaml'))
|
||||||
skillRow.forEach((skill, skillIndex) => {
|
.toString('utf-8')
|
||||||
if (krData.skillRows?.[skillRowIndex]?.[skillIndex]?.name != null) {
|
)
|
||||||
skill.krName = krData.skillRows?.[skillRowIndex]?.[skillIndex]?.name
|
}
|
||||||
}
|
const elfs = cachedData
|
||||||
if (
|
|
||||||
krData.skillRows?.[skillRowIndex]?.[skillIndex]?.description != null
|
|
||||||
) {
|
|
||||||
skill.krDescription =
|
|
||||||
krData.skillRows?.[skillRowIndex]?.[skillIndex]?.description
|
|
||||||
}
|
|
||||||
})
|
|
||||||
})
|
|
||||||
} catch (error) {
|
|
||||||
// console.warn('Failed to read', krDataFilePath)
|
|
||||||
// console.warn(error)
|
|
||||||
}
|
|
||||||
|
|
||||||
return data
|
const localized = (elfs as any[])
|
||||||
})
|
.map((elf) => {
|
||||||
.sort((a, b) => {
|
|
||||||
let compareResult = 0
|
|
||||||
|
|
||||||
compareResult = compareVersion(b.version, a.version)
|
|
||||||
|
|
||||||
if (compareResult !== 0) {
|
|
||||||
return compareResult
|
|
||||||
}
|
|
||||||
compareResult = a.name
|
|
||||||
.replace(/ \(.\)/, '')
|
|
||||||
.localeCompare(b.name.replace(/ \(.\)/, ''))
|
|
||||||
|
|
||||||
return compareResult
|
|
||||||
})
|
|
||||||
|
|
||||||
const elfMap = elfDataList.reduce((map, elf) => {
|
|
||||||
map.set(elf.id, elf)
|
|
||||||
return map
|
|
||||||
}, new Map<string, ElfData>())
|
|
||||||
|
|
||||||
export function listElfs() {
|
|
||||||
return elfDataList
|
|
||||||
}
|
|
||||||
|
|
||||||
export function getElfById(id: string) {
|
|
||||||
return elfMap.get(id)
|
|
||||||
}
|
|
||||||
|
|
||||||
function parseElfData(rawData: string) {
|
|
||||||
const [name, ...skillRowSections] = rawData.split('\n## ')
|
|
||||||
const skillRows = skillRowSections.map((skillRowSection) => {
|
|
||||||
const skillSections = skillRowSection.split('\n### ')
|
|
||||||
return skillSections.map((skillSection) => {
|
|
||||||
const [name, description] = skillSection
|
|
||||||
.split('\n\n')
|
|
||||||
.map((data) => data.replace(/#+\s/, '').trim())
|
|
||||||
return {
|
return {
|
||||||
name,
|
...omit(['krName', 'krDescription'], elf),
|
||||||
description: description.replace(/\\\*/g, '*'),
|
name: locale === 'ko-KR' ? elf.krName : elf.name,
|
||||||
}
|
skillRows: elf.skillRows.map((row: any[]) => row.map(localizeSkill)),
|
||||||
|
} as any
|
||||||
})
|
})
|
||||||
})
|
.sort((a, b) => {
|
||||||
|
let compareResult = 0
|
||||||
|
|
||||||
return {
|
compareResult = compareVersion(b.version, a.version)
|
||||||
name: name.replace(/#+\s/, '').trim(),
|
|
||||||
skillRows,
|
if (compareResult !== 0) {
|
||||||
|
return compareResult
|
||||||
|
}
|
||||||
|
compareResult = a.name
|
||||||
|
.replace(/ \(.\)/, '')
|
||||||
|
.localeCompare(b.name.replace(/ \(.\)/, ''))
|
||||||
|
|
||||||
|
return compareResult
|
||||||
|
})
|
||||||
|
|
||||||
|
return localized
|
||||||
|
|
||||||
|
function localizeSkill(skill: any) {
|
||||||
|
return {
|
||||||
|
...omit(['krName', 'krDescription'], skill),
|
||||||
|
name: locale === 'ko-KR' ? skill.krName : skill.name,
|
||||||
|
description: locale === 'ko-KR' ? skill.krDescription : skill.description,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getElfById(id: string, locale?: string) {
|
||||||
|
return listElfs(locale).find((elf) => elf.id === id, locale)
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user