From b725c41868c32ea83f9b01f2b210a441c4bbb4dc Mon Sep 17 00:00:00 2001 From: Failchon Date: Sat, 25 Jan 2025 20:31:18 +0200 Subject: [PATCH 1/5] Feature: Display the amount of builds the artefact is used on --- .../src/components/artifact/ArtifactCard.tsx | 79 ++++++++++++++++++- 1 file changed, 75 insertions(+), 4 deletions(-) diff --git a/libs/gi/ui/src/components/artifact/ArtifactCard.tsx b/libs/gi/ui/src/components/artifact/ArtifactCard.tsx index 2fb7385a78..e47b653b38 100644 --- a/libs/gi/ui/src/components/artifact/ArtifactCard.tsx +++ b/libs/gi/ui/src/components/artifact/ArtifactCard.tsx @@ -1,5 +1,6 @@ 'use client' // use client due to hydration difference between client rendering and server in translation +import { useBoolState } from '@genshin-optimizer/common/react-util' import { iconInlineProps } from '@genshin-optimizer/common/svgicons' import { BootstrapTooltip, @@ -8,7 +9,9 @@ import { ConditionalWrapper, InfoTooltip, InfoTooltipInline, + ModalWrapper, NextImage, + SqBadge, StarsDisplay, } from '@genshin-optimizer/common/ui' import { clamp, clamp01, getUnitStr } from '@genshin-optimizer/common/util' @@ -23,7 +26,7 @@ import { allSubstatKeys, } from '@genshin-optimizer/gi/consts' import type { ICachedArtifact, ICachedSubstat } from '@genshin-optimizer/gi/db' -import { useArtifact } from '@genshin-optimizer/gi/db-ui' +import { useArtifact, useDatabase } from '@genshin-optimizer/gi/db-ui' import { SlotIcon, StatIcon } from '@genshin-optimizer/gi/svgicons' import { artDisplayValue, @@ -40,7 +43,9 @@ import { Button, CardActionArea, CardContent, + CardHeader, Chip, + Divider, IconButton, Skeleton, SvgIcon, @@ -49,7 +54,7 @@ import { import type { ReactNode } from 'react' import { Suspense, useCallback, useMemo } from 'react' import { useTranslation } from 'react-i18next' -import { ExcludeIcon } from '../../consts' +import { CloseIcon, ExcludeIcon } from '../../consts' import { PercentBadge } from '../PercentBadge' import { LocationAutocomplete, LocationName } from '../character' import { ArtifactSetTooltipContent } from './ArtifactSetTooltip' @@ -96,7 +101,7 @@ export function ArtifactCardObj({ } & Data) { const { t } = useTranslation(['artifact', 'ui']) const { t: tk } = useTranslation('statKey_gen') - + const [showDup, onShowDup, onHideDup] = useBoolState(false) const wrapperFunc = useCallback( (children: ReactNode) => ( const slotDesc = @@ -178,6 +192,13 @@ export function ArtifactCardObj({ /> } > + + + )} - + {(setKey && ) || 'Artifact Set'}{' '} {setKey && ( @@ -358,6 +387,13 @@ export function ArtifactCardObj({ title={} /> )} + + {numberOfBuilds} Builds + @@ -488,3 +524,38 @@ function SubstatDisplay({ ) } + +function DupModal({ + show, + onHide, + names, +}: { + show: boolean + onHide: () => void + names: string +}) { + return ( + + + + Used in: {names} + + } + action={ + + + + } + /> + + + + ) +} From a91a98c4184ea52fb9a333ed7df579e4728272b7 Mon Sep 17 00:00:00 2001 From: Failchon Date: Sat, 25 Jan 2025 21:51:01 +0200 Subject: [PATCH 2/5] Feature: Added translation, reafactor some code --- .../assets/locales/en/artifact.json | 5 ++- .../src/components/artifact/ArtifactCard.tsx | 33 ++++++++++--------- 2 files changed, 22 insertions(+), 16 deletions(-) diff --git a/libs/gi/localization/assets/locales/en/artifact.json b/libs/gi/localization/assets/locales/en/artifact.json index df98210d51..233be90400 100644 --- a/libs/gi/localization/assets/locales/en/artifact.json +++ b/libs/gi/localization/assets/locales/en/artifact.json @@ -121,5 +121,8 @@ "rvSliderBtn": { "maximum": "MRV", "current": "RV" - } + }, + "builds_one": "{{count}} Build", + "builds_other": "{{count}} Builds", + "usage": "Used in: " } diff --git a/libs/gi/ui/src/components/artifact/ArtifactCard.tsx b/libs/gi/ui/src/components/artifact/ArtifactCard.tsx index e47b653b38..c8afe2871e 100644 --- a/libs/gi/ui/src/components/artifact/ArtifactCard.tsx +++ b/libs/gi/ui/src/components/artifact/ArtifactCard.tsx @@ -101,7 +101,7 @@ export function ArtifactCardObj({ } & Data) { const { t } = useTranslation(['artifact', 'ui']) const { t: tk } = useTranslation('statKey_gen') - const [showDup, onShowDup, onHideDup] = useBoolState(false) + const [showUsage, onShowUsage, onHideUsage] = useBoolState(false) const wrapperFunc = useCallback( (children: ReactNode) => ( const slotDesc = @@ -193,10 +193,10 @@ export function ArtifactCardObj({ } > - )} - {numberOfBuilds} Builds + {t('builds', { count: numberOfBuilds })} @@ -525,14 +528,14 @@ function SubstatDisplay({ ) } -function DupModal({ +function ArtifactBuildUsageModal({ show, onHide, - names, + buildNames, }: { show: boolean onHide: () => void - names: string + buildNames: string }) { return ( @@ -545,7 +548,7 @@ function DupModal({ display="flex" alignItems="center" > - Used in: {names} + {buildNames} } action={ From 807fb424cc00c4ae78f4428b7476a699be0571f9 Mon Sep 17 00:00:00 2001 From: Failchon Date: Sat, 25 Jan 2025 22:33:31 +0200 Subject: [PATCH 3/5] Refactor code --- .../assets/locales/en/artifact.json | 2 +- .../src/components/artifact/ArtifactCard.tsx | 21 ++++++++++++++----- 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/libs/gi/localization/assets/locales/en/artifact.json b/libs/gi/localization/assets/locales/en/artifact.json index 233be90400..9ad97bdab5 100644 --- a/libs/gi/localization/assets/locales/en/artifact.json +++ b/libs/gi/localization/assets/locales/en/artifact.json @@ -124,5 +124,5 @@ }, "builds_one": "{{count}} Build", "builds_other": "{{count}} Builds", - "usage": "Used in: " + "artifactUsage": "Artifact is used in the following builds: " } diff --git a/libs/gi/ui/src/components/artifact/ArtifactCard.tsx b/libs/gi/ui/src/components/artifact/ArtifactCard.tsx index c8afe2871e..2c8c7fc12a 100644 --- a/libs/gi/ui/src/components/artifact/ArtifactCard.tsx +++ b/libs/gi/ui/src/components/artifact/ArtifactCard.tsx @@ -45,8 +45,10 @@ import { CardContent, CardHeader, Chip, - Divider, IconButton, + List, + ListItem, + ListItemText, Skeleton, SvgIcon, Typography, @@ -196,7 +198,8 @@ export function ArtifactCardObj({ void - buildNames: string + buildNames: string[] + usageText: string }) { return ( @@ -548,7 +553,7 @@ function ArtifactBuildUsageModal({ display="flex" alignItems="center" > - {buildNames} + {usageText} } action={ @@ -557,7 +562,13 @@ function ArtifactBuildUsageModal({ } /> - + + {buildNames.map((name, index) => ( + + + + ))} + ) From 9e3b0a03d12193d0391b0e861d24c457b84ca4d5 Mon Sep 17 00:00:00 2001 From: Failchon Date: Sat, 25 Jan 2025 22:48:08 +0200 Subject: [PATCH 4/5] Refactor using memo() --- .../ui/src/components/artifact/ArtifactCard.tsx | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/libs/gi/ui/src/components/artifact/ArtifactCard.tsx b/libs/gi/ui/src/components/artifact/ArtifactCard.tsx index 2c8c7fc12a..7b0b2cdd9a 100644 --- a/libs/gi/ui/src/components/artifact/ArtifactCard.tsx +++ b/libs/gi/ui/src/components/artifact/ArtifactCard.tsx @@ -161,15 +161,16 @@ export function ArtifactCardObj({ level ) const database = useDatabase() - - const builds = database.builds.data - const buildNames = [] - for (const buildId in builds) { - if (builds[buildId]?.artifactIds[artifact.slotKey] === artifact.id) { - buildNames.push(builds[buildId].name) + const { buildNames, numberOfBuilds } = useMemo(() => { + const names: string[] = [] + const builds = database.builds.data + for (const buildId in builds) { + if (builds[buildId]?.artifactIds[artifact.slotKey] === artifact.id) { + names.push(builds[buildId].name) + } } - } - const numberOfBuilds = buildNames.length + return { buildNames: names, numberOfBuilds: names.length } + }, [database.builds.data, artifact.slotKey, artifact.id]) const artifactValid = maxEfficiency !== 0 const slotName = const slotDesc = From cf84a791ae8dc4ce1c231270653af9b4795bb2f7 Mon Sep 17 00:00:00 2001 From: Failchon Date: Sun, 26 Jan 2025 21:03:48 +0200 Subject: [PATCH 5/5] Refactor changes, added loadout name and icons --- .../Database/DataManagers/BuildDataManager.ts | 3 + .../assets/locales/en/artifact.json | 2 +- .../src/components/artifact/ArtifactCard.tsx | 68 +++++++++++++------ 3 files changed, 51 insertions(+), 22 deletions(-) diff --git a/libs/gi/db/src/Database/DataManagers/BuildDataManager.ts b/libs/gi/db/src/Database/DataManagers/BuildDataManager.ts index f6fc68e950..eb6f46b969 100644 --- a/libs/gi/db/src/Database/DataManagers/BuildDataManager.ts +++ b/libs/gi/db/src/Database/DataManagers/BuildDataManager.ts @@ -9,6 +9,7 @@ import { defaultInitialWeaponKey, initialWeapon } from './WeaponDataManager' export interface Build { name: string description: string + id: string weaponId?: string artifactIds: Record @@ -29,6 +30,7 @@ export class BuildDataManager extends DataManager< } override validate(obj: unknown): Build | undefined { let { name, description, weaponId, artifactIds } = obj as Build + const { id } = obj as Build if (typeof name !== 'string') name = 'Build Name' if (typeof description !== 'string') description = '' if (weaponId && !this.database.weapons.get(weaponId)) weaponId = undefined @@ -62,6 +64,7 @@ export class BuildDataManager extends DataManager< description, weaponId, artifactIds, + id, } } diff --git a/libs/gi/localization/assets/locales/en/artifact.json b/libs/gi/localization/assets/locales/en/artifact.json index 9ad97bdab5..56d8b2fbe0 100644 --- a/libs/gi/localization/assets/locales/en/artifact.json +++ b/libs/gi/localization/assets/locales/en/artifact.json @@ -124,5 +124,5 @@ }, "builds_one": "{{count}} Build", "builds_other": "{{count}} Builds", - "artifactUsage": "Artifact is used in the following builds: " + "artifactUsage": "Artifact is used in the following loadouts and builds: " } diff --git a/libs/gi/ui/src/components/artifact/ArtifactCard.tsx b/libs/gi/ui/src/components/artifact/ArtifactCard.tsx index 7b0b2cdd9a..ddc981837a 100644 --- a/libs/gi/ui/src/components/artifact/ArtifactCard.tsx +++ b/libs/gi/ui/src/components/artifact/ArtifactCard.tsx @@ -18,6 +18,7 @@ import { clamp, clamp01, getUnitStr } from '@genshin-optimizer/common/util' import { artifactAsset } from '@genshin-optimizer/gi/assets' import type { ArtifactRarity, + CharacterKey, LocationKey, SubstatKey, } from '@genshin-optimizer/gi/consts' @@ -48,6 +49,7 @@ import { IconButton, List, ListItem, + ListItemIcon, ListItemText, Skeleton, SvgIcon, @@ -56,9 +58,9 @@ import { import type { ReactNode } from 'react' import { Suspense, useCallback, useMemo } from 'react' import { useTranslation } from 'react-i18next' -import { CloseIcon, ExcludeIcon } from '../../consts' +import { CloseIcon, ExcludeIcon, LoadoutIcon } from '../../consts' import { PercentBadge } from '../PercentBadge' -import { LocationAutocomplete, LocationName } from '../character' +import { CharIconSide, LocationAutocomplete, LocationName } from '../character' import { ArtifactSetTooltipContent } from './ArtifactSetTooltip' import { ArtifactSetName, @@ -161,16 +163,28 @@ export function ArtifactCardObj({ level ) const database = useDatabase() - const { buildNames, numberOfBuilds } = useMemo(() => { - const names: string[] = [] - const builds = database.builds.data - for (const buildId in builds) { - if (builds[buildId]?.artifactIds[artifact.slotKey] === artifact.id) { - names.push(builds[buildId].name) - } - } - return { buildNames: names, numberOfBuilds: names.length } - }, [database.builds.data, artifact.slotKey, artifact.id]) + const builds: { + loadoutName: string + buildName: string + charKey: CharacterKey + }[] = useMemo(() => { + return database.builds.values + .filter( + ({ artifactIds }) => artifactIds[artifact.slotKey] === artifact.id + ) + .flatMap(({ id, name }) => { + const buildName = name + return database.teamChars.values + .filter(({ buildIds }) => buildIds.includes(id)) + .map(({ key, name }) => { + return { + charKey: key, + buildName, + loadoutName: name, + } + }) + }) + }, [database.builds, database.teamChars, artifact.slotKey, artifact.id]) const artifactValid = maxEfficiency !== 0 const slotName = const slotDesc = @@ -199,8 +213,8 @@ export function ArtifactCardObj({ - {t('builds', { count: numberOfBuilds })} + {t('builds', { count: builds.length })} @@ -535,13 +549,17 @@ function SubstatDisplay({ function ArtifactBuildUsageModal({ show, onHide, - buildNames, usageText, + builds, }: { show: boolean onHide: () => void - buildNames: string[] usageText: string + builds: { + loadoutName: string + buildName: string + charKey: CharacterKey + }[] }) { return ( @@ -564,9 +582,17 @@ function ArtifactBuildUsageModal({ } /> - {buildNames.map((name, index) => ( + {builds.map((build, index) => ( - + + + + + ))}