import type { ItemStack } from 'deepslate/core' import { useCallback, useEffect, useMemo, useRef, useState } from 'preact/hooks' import { useVersion } from '../contexts/Version.jsx' import { useAsync } from '../hooks/useAsync.js' import { fetchItemComponents } from '../services/index.js' import { ResolvedItem } from '../services/ResolvedItem.js' import { renderItem } from '../services/Resources.js' import { jsonToNbt } from '../Utils.js' import { ItemTooltip } from './ItemTooltip.jsx' import { Octicon } from './Octicon.jsx' interface Props { item: ItemStack, slotDecoration?: boolean, tooltip?: boolean, advancedTooltip?: boolean, } export function ItemDisplay({ item, slotDecoration, tooltip, advancedTooltip }: Props) { const { version } = useVersion() const el = useRef(null) const [tooltipOffset, setTooltipOffset] = useState<[number, number]>([0, 0]) const [tooltipSwap, setTooltipSwap] = useState(false) useEffect(() => { const onMove = (e: MouseEvent) => { requestAnimationFrame(() => { const { right, width } = el.current!.getBoundingClientRect() const swap = right + 200 > document.body.clientWidth setTooltipSwap(swap) setTooltipOffset([(swap ? width - e.offsetX : e.offsetX) + 20, e.offsetY - 40]) }) } el.current?.addEventListener('mousemove', onMove) return () => el.current?.removeEventListener('mousemove', onMove) }, []) const { value: baseComponents } = useAsync(() => fetchItemComponents(version), [version]) const itemResolver = useCallback((item: ItemStack) => { const base = baseComponents?.get(item.id.toString()) ?? new Map() return new ResolvedItem(item, new Map([...base.entries()].map(([k, v]) => [k, jsonToNbt(v)]))) }, [baseComponents]) const resolvedItem = useMemo(() => { return itemResolver(item) }, [item, itemResolver]) const maxDamage = resolvedItem.getMaxDamage() const damage = resolvedItem.getDamage() return
{item.count !== 1 && <> {item.count} {item.count} } {slotDecoration && <> {(maxDamage > 0 && damage > 0) && }
} {tooltip !== false && !resolvedItem.has('hide_tooltip') &&
}
} interface ResolvedProps extends Props { item: ResolvedItem baseComponents: Map> | undefined } function RenderedItem({ item, baseComponents }: ResolvedProps) { const { version } = useVersion() const { value: src } = useAsync(async () => { if (!baseComponents) { return undefined } return renderItem(version, item, baseComponents) }, [version, item, baseComponents]) if (src) { return <> {item.id.toString()} {item.hasFoil() &&
} } return
{Octicon.package}
}