Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add character rarity to filter options in Characters page and Allowed Characters for Artifacts #1357

Merged
merged 7 commits into from
Dec 3, 2023
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import type { CharacterRarityKey } from '@genshin-optimizer/consts'
import { allCharacterRarityKeys } from '@genshin-optimizer/consts'
import StarRoundedIcon from '@mui/icons-material/StarRounded'
import { Box, Chip, ToggleButton, useMediaQuery, useTheme } from '@mui/material'
import { handleMultiSelect } from '../../Util/MultiSelect'
import type { SolidToggleButtonGroupProps } from '../SolidToggleButtonGroup'
import SolidToggleButtonGroup from '../SolidToggleButtonGroup'
type CharacterRarityToggleProps = Omit<
SolidToggleButtonGroupProps,
'onChange' | 'value'
> & {
onChange: (value: CharacterRarityKey[]) => void
value: CharacterRarityKey[]
totals: Record<CharacterRarityKey, Displayable>
}
const rarityHandler = handleMultiSelect([...allCharacterRarityKeys])
export default function CharacterRarityToggle({
value,
totals,
onChange,
...props
}: CharacterRarityToggleProps) {
const theme = useTheme()
const xs = !useMediaQuery(theme.breakpoints.up('sm'))
return (
<SolidToggleButtonGroup exclusive value={value} {...props}>
{allCharacterRarityKeys.map((star) => (
<ToggleButton
key={star}
value={star}
sx={{
p: xs ? 1 : undefined,
minWidth: xs ? 0 : '6em',
display: 'flex',
gap: xs ? 0 : 1,
}}
onClick={() => onChange(rarityHandler(value, star))}
>
<Box display="flex">
<strong>{star}</strong>
<StarRoundedIcon />
{!xs && <Chip label={totals[star]} size="small" />}
</Box>
</ToggleButton>
))}
</SolidToggleButtonGroup>
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { Box, Chip, ToggleButton, useMediaQuery, useTheme } from '@mui/material'
import { handleMultiSelect } from '../../Util/MultiSelect'
import type { SolidToggleButtonGroupProps } from '../SolidToggleButtonGroup'
import SolidToggleButtonGroup from '../SolidToggleButtonGroup'
type RarityToggleProps = Omit<
type WeaponRarityToggleProps = Omit<
SolidToggleButtonGroupProps,
'onChange' | 'value'
> & {
Expand All @@ -14,12 +14,12 @@ type RarityToggleProps = Omit<
totals: Record<RarityKey, Displayable>
}
const rarityHandler = handleMultiSelect([...allRarityKeys])
export default function RarityToggle({
export default function WeaponRarityToggle({
value,
totals,
onChange,
...props
}: RarityToggleProps) {
}: WeaponRarityToggleProps) {
const theme = useTheme()
const xs = !useMediaQuery(theme.breakpoints.up('sm'))
return (
Expand All @@ -30,7 +30,7 @@ export default function RarityToggle({
value={star}
sx={{
p: xs ? 1 : undefined,
minWidth: xs ? 0 : '7em',
minWidth: xs ? 0 : '6em',
display: 'flex',
gap: xs ? 0 : 1,
}}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ export default function WeaponToggle({
value={wt}
sx={{
p: xs ? 1 : undefined,
minWidth: xs ? 0 : '7em',
minWidth: xs ? 0 : '6em',
display: 'flex',
gap: xs ? 0 : 1,
}}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ import CloseButton from '../CloseButton'
import ImgIcon from '../Image/ImgIcon'
import ModalWrapper from '../ModalWrapper'
import { StarsDisplay } from '../StarDisplay'
import RarityToggle from '../ToggleButton/RarityToggle'
import WeaponRarityToggle from '../ToggleButton/WeaponRarityToggle'
import WeaponToggle from '../ToggleButton/WeaponToggle'

type WeaponSelectionModalProps = {
Expand Down Expand Up @@ -132,7 +132,7 @@ export default function WeaponSelectionModal({
/>
</Grid>
<Grid item>
<RarityToggle
<WeaponRarityToggle
sx={{ height: '100%' }}
onChange={(rarity) => database.displayWeapon.set({ rarity })}
value={rarity}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
import type { ElementKey, WeaponTypeKey } from '@genshin-optimizer/consts'
import { allElementKeys, allWeaponTypeKeys } from '@genshin-optimizer/consts'
import type {
CharacterRarityKey,
ElementKey,
WeaponTypeKey,
} from '@genshin-optimizer/consts'
import {
allElementKeys,
allWeaponTypeKeys,
allCharacterRarityKeys,
} from '@genshin-optimizer/consts'
import { validateArr } from '@genshin-optimizer/util'
import type { CharacterSortKey } from '../../Util/CharacterSort'
import { characterSortKeys } from '../../Util/CharacterSort'
Expand All @@ -11,6 +19,7 @@ export interface IDisplayCharacterEntry {
ascending: boolean
weaponType: WeaponTypeKey[]
element: ElementKey[]
rarity: CharacterRarityKey[]
pageIndex: number
}

Expand All @@ -19,6 +28,7 @@ const initialState = (): IDisplayCharacterEntry => ({
ascending: false,
weaponType: [...allWeaponTypeKeys],
element: [...allElementKeys],
rarity: [...allCharacterRarityKeys],
pageIndex: 0,
})

Expand All @@ -33,14 +43,15 @@ export class DisplayCharacterEntry extends DataEntry<
}
override validate(obj: any): IDisplayCharacterEntry | undefined {
if (typeof obj !== 'object') return undefined
let { sortType, ascending, weaponType, element, pageIndex } = obj
let { sortType, ascending, weaponType, element, rarity, pageIndex } = obj

//Disallow sorting by "new" explicitly.
if (sortType === 'new' || !characterSortKeys.includes(sortType))
sortType = 'level'
if (typeof ascending !== 'boolean') ascending = false
weaponType = validateArr(weaponType, allWeaponTypeKeys)
element = validateArr(element, allElementKeys)
rarity = validateArr(rarity, allCharacterRarityKeys)
if (
typeof pageIndex !== 'number' ||
pageIndex < 0 ||
Expand All @@ -52,6 +63,7 @@ export class DisplayCharacterEntry extends DataEntry<
ascending,
weaponType,
element,
rarity,
pageIndex,
}
return data
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
allArtifactSlotKeys,
allElementKeys,
allWeaponTypeKeys,
allCharacterRarityKeys,
charKeyToLocCharKey,
} from '@genshin-optimizer/consts'
import { useBoolState, useForceUpdate } from '@genshin-optimizer/react-util'
Expand Down Expand Up @@ -45,6 +46,7 @@ import SolidToggleButtonGroup from '../../../../../Components/SolidToggleButtonG
import SqBadge from '../../../../../Components/SqBadge'
import ElementToggle from '../../../../../Components/ToggleButton/ElementToggle'
import WeaponToggle from '../../../../../Components/ToggleButton/WeaponToggle'
import CharacterRarityToggle from '../../../../../Components/ToggleButton/CharacterRarityToggle'
import { CharacterContext } from '../../../../../Context/CharacterContext'
import { SillyContext } from '../../../../../Context/SillyContext'
import { getCharSheet } from '../../../../../Data/Characters'
Expand Down Expand Up @@ -89,6 +91,10 @@ export default function AllowChar({
const deferredElementKeys = useDeferredValue(elementKeys)
const [weaponTypeKeys, setWeaponTypeKeys] = useState([...allWeaponTypeKeys])
const deferredWeaponTypeKeys = useDeferredValue(weaponTypeKeys)
const [characterRarityKeys, setCharacterRarityKeys] = useState([
...allCharacterRarityKeys,
])
const deferredCharacterRarityKeys = useDeferredValue(characterRarityKeys)

const charKeyMap: Dict<CharacterKey, ICachedCharacter> = useMemo(
() =>
Expand All @@ -103,6 +109,7 @@ export default function AllowChar({
{
element: deferredElementKeys,
weaponType: deferredWeaponTypeKeys,
rarity: deferredCharacterRarityKeys,
name: deferredSearchTerm,
},
characterFilterConfigs(database, silly)
Expand All @@ -117,6 +124,7 @@ export default function AllowChar({
characterKey,
deferredElementKeys,
deferredWeaponTypeKeys,
deferredCharacterRarityKeys,
deferredSearchTerm,
silly,
]
Expand All @@ -139,10 +147,16 @@ export default function AllowChar({
})
.map(([ck]) => charKeyToLocCharKey(ck))

const { elementTotals, weaponTypeTotals, locListTotals } = useMemo(() => {
const {
elementTotals,
weaponTypeTotals,
characterRarityTotals,
locListTotals,
} = useMemo(() => {
const catKeys = {
elementTotals: [...allElementKeys],
weaponTypeTotals: [...allWeaponTypeKeys],
characterRarityTotals: [...allCharacterRarityKeys],
locListTotals: ['allowed', 'excluded'],
} as const
return bulkCatTotal(catKeys, (ctMap) =>
Expand All @@ -158,6 +172,11 @@ export default function AllowChar({
ctMap.weaponTypeTotals[weaponTypeKey].total++
if (charKeyMap[ck]) ctMap.weaponTypeTotals[weaponTypeKey].current++

const characterRarityKey = sheet.rarity
ctMap.characterRarityTotals[characterRarityKey].total++
if (charKeyMap[ck])
ctMap.characterRarityTotals[characterRarityKey].current++

const locKey = charKeyToLocCharKey(ck)
if (locList.includes(locKey)) {
ctMap.locListTotals.allowed.total++
Expand Down Expand Up @@ -322,6 +341,13 @@ export default function AllowChar({
totals={elementTotals}
size="small"
/>
<CharacterRarityToggle
sx={{ height: '100%' }}
onChange={setCharacterRarityKeys}
value={deferredCharacterRarityKeys}
totals={characterRarityTotals}
size="small"
/>
</Box>
</Stack>
</CardContent>
Expand Down
36 changes: 33 additions & 3 deletions apps/frontend/src/app/PageCharacter/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import type { CharacterKey } from '@genshin-optimizer/consts'
import {
allElementKeys,
allWeaponTypeKeys,
allCharacterRarityKeys,
charKeyToLocGenderedCharKey,
} from '@genshin-optimizer/consts'
import { useForceUpdate, useMediaQueryUp } from '@genshin-optimizer/react-util'
Expand Down Expand Up @@ -46,6 +47,7 @@ import CharacterCard from '../Components/Character/CharacterCard'
import SortByButton from '../Components/SortByButton'
import ElementToggle from '../Components/ToggleButton/ElementToggle'
import WeaponToggle from '../Components/ToggleButton/WeaponToggle'
import CharacterRarityToggle from '../Components/ToggleButton/CharacterRarityToggle'
import { SillyContext } from '../Context/SillyContext'
import { getCharSheet } from '../Data/Characters'
import { getWeaponSheet } from '../Data/Weapons'
Expand Down Expand Up @@ -136,11 +138,11 @@ export default function PageCharacter() {
const { charKeyList, totalCharNum } = useMemo(() => {
const chars = database.chars.keys
const totalCharNum = chars.length
const { element, weaponType, sortType, ascending } = deferredState
const { element, weaponType, rarity, sortType, ascending } = deferredState
const charKeyList = database.chars.keys
.filter(
filterFunction(
{ element, weaponType, name: deferredSearchTerm },
{ element, weaponType, rarity, name: deferredSearchTerm },
characterFilterConfigs(database, silly)
)
)
Expand All @@ -155,7 +157,14 @@ export default function PageCharacter() {
return deferredDbDirty && { charKeyList, totalCharNum }
}, [database, deferredState, deferredSearchTerm, silly, deferredDbDirty])

const { weaponType, element, sortType, ascending, pageIndex = 0 } = state
const {
weaponType,
element,
rarity,
sortType,
ascending,
pageIndex = 0,
} = state

const { charKeyListToShow, numPages, currentPageIndex } = useMemo(() => {
const numPages = Math.ceil(charKeyList.length / maxNumToDisplay)
Expand Down Expand Up @@ -201,6 +210,18 @@ export default function PageCharacter() {
[database, charKeyList]
)

const rarityTotals = useMemo(
() =>
catTotal(allCharacterRarityKeys, (ct) =>
Object.entries(database.chars.data).forEach(([ck, char]) => {
const eleKey = getCharSheet(char.key, database.gender).rarity
ct[eleKey].total++
if (charKeyList.includes(ck)) ct[eleKey].current++
})
),
[database, charKeyList]
)

return (
<Box my={1} display="flex" flexDirection="column" gap={1}>
<Suspense fallback={false}>
Expand Down Expand Up @@ -236,6 +257,15 @@ export default function PageCharacter() {
size="small"
/>
</Grid>
<Grid item>
<CharacterRarityToggle
sx={{ height: '100%' }}
onChange={(rarity) => database.displayCharacter.set({ rarity })}
value={rarity}
totals={rarityTotals}
size="small"
/>
</Grid>
<Grid item flexGrow={1} />
<Grid item>
<TextField
Expand Down
4 changes: 2 additions & 2 deletions apps/frontend/src/app/PageWeapon/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ import ReactGA from 'react-ga4'
import { Trans, useTranslation } from 'react-i18next'
import CardDark from '../Components/Card/CardDark'
import SortByButton from '../Components/SortByButton'
import RarityToggle from '../Components/ToggleButton/RarityToggle'
import WeaponRarityToggle from '../Components/ToggleButton/WeaponRarityToggle'
import WeaponToggle from '../Components/ToggleButton/WeaponToggle'
import { getWeaponSheet } from '../Data/Weapons'
import { DatabaseContext } from '../Database/Database'
Expand Down Expand Up @@ -228,7 +228,7 @@ export default function PageWeapon() {
totals={weaponTotals}
size="small"
/>
<RarityToggle
<WeaponRarityToggle
sx={{ height: '100%' }}
onChange={(rarity) => database.displayWeapon.set({ rarity })}
value={rarity}
Expand Down
7 changes: 7 additions & 0 deletions apps/frontend/src/app/Util/CharacterSort.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@ import type {
CharacterKey,
ElementKey,
WeaponTypeKey,
CharacterRarityKey,
} from '@genshin-optimizer/consts'
import {
allElementKeys,
allWeaponTypeKeys,
allCharacterRarityKeys,
charKeyToLocCharKey,
charKeyToLocGenderedCharKey,
} from '@genshin-optimizer/consts'
Expand Down Expand Up @@ -48,6 +50,7 @@ export function characterSortConfigs(
export const characterFilterKeys = [
'element',
'weaponType',
'rarity',
'name',
'new',
] as const
Expand All @@ -65,6 +68,8 @@ export function characterFilterConfigs(
element: (ck, filter) => filter.includes(getCharEle(ck)),
weaponType: (ck, filter) =>
filter.includes(allStats.char.data[charKeyToLocCharKey(ck)].weaponType),
rarity: (ck, filter) =>
filter.includes(allStats.char.data[charKeyToLocCharKey(ck)].rarity),
name: (ck, filter) =>
filter === undefined ||
i18n
Expand Down Expand Up @@ -101,11 +106,13 @@ export const initialCharacterDisplayState = (): {
ascending: boolean
weaponType: WeaponTypeKey[]
element: ElementKey[]
rarity: CharacterRarityKey[]
pageIndex: number
} => ({
sortType: characterSortKeys[0],
ascending: false,
weaponType: [...allWeaponTypeKeys],
element: [...allElementKeys],
rarity: [...allCharacterRarityKeys],
pageIndex: 0,
})
Loading
Loading