Improve battlesuit filter behavior
This commit is contained in:
@@ -8,7 +8,7 @@ interface FilterButtonProps {
|
||||
active?: boolean
|
||||
icon?: string
|
||||
label: string
|
||||
value: string
|
||||
href: string
|
||||
m?: string | number
|
||||
close?: () => void
|
||||
}
|
||||
@@ -17,14 +17,14 @@ const FilterButton = ({
|
||||
active = false,
|
||||
icon,
|
||||
label,
|
||||
value,
|
||||
href,
|
||||
m,
|
||||
close,
|
||||
}: FilterButtonProps) => {
|
||||
const { push } = useRouter()
|
||||
return (
|
||||
<Link
|
||||
href={`?filter=${value}`}
|
||||
href={href}
|
||||
m={m}
|
||||
py={1}
|
||||
px={2}
|
||||
@@ -36,7 +36,7 @@ const FilterButton = ({
|
||||
if (close != null) {
|
||||
close()
|
||||
}
|
||||
push({ query: { filter: value } }, undefined, { shallow: true })
|
||||
push(href, href, { shallow: true })
|
||||
}}
|
||||
>
|
||||
{icon != null && (
|
||||
|
||||
@@ -54,26 +54,43 @@ const BattlesuitListPage = ({ battlesuits }: BattlesuitListPageProps) => {
|
||||
setHiddenFilters(true)
|
||||
}, [])
|
||||
|
||||
const filter = useMemo(() => {
|
||||
if (query.filter == null) {
|
||||
const valkyrieFilter = useMemo(() => {
|
||||
if (query.valkyrie == null) {
|
||||
return 'all'
|
||||
}
|
||||
|
||||
return typeof query.filter === 'string' ? query.filter : query.filter[0]
|
||||
return typeof query.valkyrie === 'string'
|
||||
? query.valkyrie
|
||||
: query.valkyrie[0]
|
||||
}, [query])
|
||||
|
||||
const battlesuitList = useMemo(() => {
|
||||
return battlesuits.map((battlesuit) => {
|
||||
const hidden = isBattlesuitHidden(battlesuit, filter)
|
||||
return (
|
||||
<BattlesuitCard
|
||||
key={battlesuit.id}
|
||||
battlesuit={battlesuit}
|
||||
hidden={hidden}
|
||||
/>
|
||||
)
|
||||
})
|
||||
}, [battlesuits, filter])
|
||||
const featureFilter = useMemo(() => {
|
||||
if (query.feature == null) {
|
||||
return 'all'
|
||||
}
|
||||
|
||||
return typeof query.feature === 'string' ? query.feature : query.feature[0]
|
||||
}, [query])
|
||||
|
||||
const battlesuitsFiteredByValkyrie = useMemo(() => {
|
||||
return battlesuits.filter((battlesuit) =>
|
||||
isValkyrieFilterMatching(battlesuit, valkyrieFilter)
|
||||
)
|
||||
}, [battlesuits, valkyrieFilter])
|
||||
|
||||
const availableFeatureSet = battlesuitsFiteredByValkyrie.reduce(
|
||||
(set, battlesuit) => {
|
||||
battlesuit.features.forEach((feature) => set.add(feature))
|
||||
return set
|
||||
},
|
||||
new Set()
|
||||
)
|
||||
|
||||
const battlesuitsFilteredByFeature = useMemo(() => {
|
||||
return battlesuitsFiteredByValkyrie.filter((battlesuit) =>
|
||||
isFeatureFilterMatching(battlesuit, featureFilter)
|
||||
)
|
||||
}, [battlesuitsFiteredByValkyrie, featureFilter])
|
||||
|
||||
return (
|
||||
<Honkai3rdLayout>
|
||||
@@ -117,14 +134,14 @@ const BattlesuitListPage = ({ battlesuits }: BattlesuitListPageProps) => {
|
||||
},
|
||||
}}
|
||||
>
|
||||
<Heading as='h3'>{t('battlesuits-list.filter-by-features')}</Heading>
|
||||
<Heading as='h3'>{t('battlesuits-list.filter-by-valkyries')}</Heading>
|
||||
<Flex mb={2} sx={{ flexWrap: 'wrap' }}>
|
||||
{featureFilterOptions.map(({ value, label, icon, krLabel }) => {
|
||||
{valkyrieFilterOptions.map(({ value, label, icon, krLabel }) => {
|
||||
return (
|
||||
<FilterButton
|
||||
key={value}
|
||||
active={value === filter}
|
||||
value={value}
|
||||
active={value === valkyrieFilter}
|
||||
href={`?valkyrie=${value}`}
|
||||
label={translate(locale, { 'ko-KR': krLabel }, label)}
|
||||
icon={icon}
|
||||
m={1}
|
||||
@@ -133,22 +150,28 @@ const BattlesuitListPage = ({ battlesuits }: BattlesuitListPageProps) => {
|
||||
)
|
||||
})}
|
||||
</Flex>
|
||||
|
||||
<Heading as='h3'>{t('battlesuits-list.filter-by-valkyries')}</Heading>
|
||||
<Heading as='h3'>{t('battlesuits-list.filter-by-features')}</Heading>
|
||||
<Flex mb={2} sx={{ flexWrap: 'wrap' }}>
|
||||
{valkyrieFilterOptions.map(({ value, label, icon, krLabel }) => {
|
||||
return (
|
||||
<FilterButton
|
||||
key={value}
|
||||
active={value === filter}
|
||||
value={value}
|
||||
label={translate(locale, { 'ko-KR': krLabel }, label)}
|
||||
icon={icon}
|
||||
m={1}
|
||||
close={closeFilters}
|
||||
/>
|
||||
)
|
||||
})}
|
||||
{featureFilterOptions
|
||||
.filter((filterOption) => {
|
||||
if (filterOption.value === 'all') {
|
||||
return true
|
||||
}
|
||||
return availableFeatureSet.has(filterOption.value)
|
||||
})
|
||||
.map(({ value, label, icon, krLabel }) => {
|
||||
return (
|
||||
<FilterButton
|
||||
key={value}
|
||||
active={value === featureFilter}
|
||||
href={`?valkyrie=${valkyrieFilter}&feature=${value}`}
|
||||
label={translate(locale, { 'ko-KR': krLabel }, label)}
|
||||
icon={icon}
|
||||
m={1}
|
||||
close={closeFilters}
|
||||
/>
|
||||
)
|
||||
})}
|
||||
</Flex>
|
||||
</Box>
|
||||
|
||||
@@ -158,7 +181,11 @@ const BattlesuitListPage = ({ battlesuits }: BattlesuitListPageProps) => {
|
||||
justifyContent: 'space-around',
|
||||
}}
|
||||
>
|
||||
{battlesuitList}
|
||||
{battlesuitsFilteredByFeature.map((battlesuit) => {
|
||||
return (
|
||||
<BattlesuitCard key={battlesuit.id} battlesuit={battlesuit} />
|
||||
)
|
||||
})}
|
||||
</Flex>
|
||||
</Box>
|
||||
</Honkai3rdLayout>
|
||||
@@ -184,36 +211,17 @@ export async function getStaticProps({ locale }: NextPageContext) {
|
||||
}
|
||||
}
|
||||
|
||||
function isBattlesuitHidden(
|
||||
function isValkyrieFilterMatching(
|
||||
battlesuit: BattlesuitListItemData,
|
||||
filter: string
|
||||
): boolean {
|
||||
switch (filter) {
|
||||
case 'physical':
|
||||
case 'fire-dmg':
|
||||
case 'ice-dmg':
|
||||
case 'lightning-dmg':
|
||||
case 'freeze':
|
||||
case 'paralyze':
|
||||
case 'stun':
|
||||
case 'ignite':
|
||||
case 'bleed':
|
||||
case 'heavy-atk':
|
||||
case 'weaken':
|
||||
case 'impair':
|
||||
case 'time mastery':
|
||||
case 'gather':
|
||||
case 'heal':
|
||||
case 'fast atk':
|
||||
case 'burst':
|
||||
case 'aerial':
|
||||
return !battlesuit.features.some((feature) => feature === filter)
|
||||
valkyrieFilter: string
|
||||
) {
|
||||
switch (valkyrieFilter) {
|
||||
case 'mecha':
|
||||
case 'biologic':
|
||||
case 'psychic':
|
||||
case 'quantum':
|
||||
case 'imaginary':
|
||||
return battlesuit.type !== filter
|
||||
return battlesuit.type === valkyrieFilter
|
||||
case 'kiana':
|
||||
case 'mei':
|
||||
case 'bronya':
|
||||
@@ -237,9 +245,19 @@ function isBattlesuitHidden(
|
||||
case 'eden':
|
||||
case 'griseo':
|
||||
case 'vill-v':
|
||||
return battlesuit.valkyrie !== filter
|
||||
return battlesuit.valkyrie === valkyrieFilter
|
||||
default:
|
||||
case 'all':
|
||||
return false
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
function isFeatureFilterMatching(
|
||||
battlesuit: BattlesuitListItemData,
|
||||
featureFilter: string
|
||||
) {
|
||||
if (featureFilter === 'all') {
|
||||
return true
|
||||
}
|
||||
return battlesuit.features.some((feature) => feature === featureFilter)
|
||||
}
|
||||
|
||||
@@ -41,20 +41,22 @@ const WeaponListPage = ({ weaponDataList }: WeaponListPageProps) => {
|
||||
const { query, locale } = useRouter()
|
||||
const { t } = useTranslation()
|
||||
|
||||
const filter = useMemo(() => {
|
||||
if (query.filter == null) {
|
||||
const categoryFilter = useMemo(() => {
|
||||
if (query.category == null) {
|
||||
return 'all'
|
||||
}
|
||||
|
||||
return typeof query.filter === 'string' ? query.filter : query.filter[0]
|
||||
return typeof query.category === 'string'
|
||||
? query.category
|
||||
: query.category[0]
|
||||
}, [query])
|
||||
|
||||
const weaponList = useMemo(() => {
|
||||
return weaponDataList.map((weapon) => {
|
||||
const hidden = isWeaponHidden(weapon, filter)
|
||||
const hidden = isWeaponHidden(weapon, categoryFilter)
|
||||
return <WeaponCard key={weapon.id} weapon={weapon} hidden={hidden} />
|
||||
})
|
||||
}, [weaponDataList, filter])
|
||||
}, [weaponDataList, categoryFilter])
|
||||
|
||||
return (
|
||||
<Honkai3rdLayout>
|
||||
@@ -82,8 +84,8 @@ const WeaponListPage = ({ weaponDataList }: WeaponListPageProps) => {
|
||||
return (
|
||||
<FilterButton
|
||||
key={value}
|
||||
active={value === filter}
|
||||
value={value}
|
||||
href={`?category=${value}`}
|
||||
active={value === categoryFilter}
|
||||
label={translate(locale, { 'ko-KR': krLabel }, label)}
|
||||
m={1}
|
||||
/>
|
||||
|
||||
Reference in New Issue
Block a user