mirror of
https://github.com/duckietm/Nitro-V3.git
synced 2026-06-20 15:36:18 +00:00
🆙 Fix BOTS in catalog and inventory
This commit is contained in:
@@ -12,35 +12,51 @@ export interface LayoutAvatarImageViewProps extends BaseProps<HTMLDivElement>
|
|||||||
headOnly?: boolean;
|
headOnly?: boolean;
|
||||||
direction?: number;
|
direction?: number;
|
||||||
scale?: number;
|
scale?: number;
|
||||||
|
fit?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const LayoutAvatarImageView: FC<LayoutAvatarImageViewProps> = props =>
|
export const LayoutAvatarImageView: FC<LayoutAvatarImageViewProps> = props =>
|
||||||
{
|
{
|
||||||
const { figure = '', gender = '', headOnly = false, direction = 0, scale = 1, classNames = [], style = {}, ...rest } = props;
|
const { figure = '', gender = '', headOnly = false, direction = 0, scale = 1, fit = false, classNames = [], style = {}, ...rest } = props;
|
||||||
const [ avatarUrl, setAvatarUrl ] = useState<string>(null);
|
const [ avatarUrl, setAvatarUrl ] = useState<string>(null);
|
||||||
const [ isReady, setIsReady ] = useState<boolean>(false);
|
const [ isReady, setIsReady ] = useState<boolean>(false);
|
||||||
const isDisposed = useRef(false);
|
const isDisposed = useRef(false);
|
||||||
// Request id bumped on every prop change. The SDK can call
|
|
||||||
// resetFigure asynchronously when server-side figure data lands;
|
|
||||||
// if props change in quick succession the older callback could
|
|
||||||
// otherwise overwrite the newer image. The closure captures the
|
|
||||||
// id and bails when stale.
|
|
||||||
const requestIdRef = useRef(0);
|
const requestIdRef = useRef(0);
|
||||||
|
|
||||||
const getClassNames = useMemo(() =>
|
const getClassNames = useMemo(() =>
|
||||||
{
|
{
|
||||||
const newClassNames: string[] = [ 'avatar-image relative w-[90px] h-[130px] bg-no-repeat left-[-2px] pointer-events-none' ];
|
let newClassNames: string[];
|
||||||
|
|
||||||
|
if(fit)
|
||||||
|
{
|
||||||
|
newClassNames = [ 'avatar-image absolute inset-0 pointer-events-none' ];
|
||||||
|
}
|
||||||
|
else if(headOnly)
|
||||||
|
{
|
||||||
|
newClassNames = [ 'avatar-image absolute inset-0 bg-no-repeat pointer-events-none' ];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
newClassNames = [ 'avatar-image relative w-[90px] h-[130px] bg-no-repeat left-[-2px] pointer-events-none' ];
|
||||||
|
}
|
||||||
|
|
||||||
if(classNames.length) newClassNames.push(...classNames);
|
if(classNames.length) newClassNames.push(...classNames);
|
||||||
|
|
||||||
return newClassNames;
|
return newClassNames;
|
||||||
}, [ classNames ]);
|
}, [ classNames, headOnly, fit ]);
|
||||||
|
|
||||||
const getStyle = useMemo(() =>
|
const getStyle = useMemo(() =>
|
||||||
{
|
{
|
||||||
let newStyle: CSSProperties = {};
|
let newStyle: CSSProperties = {};
|
||||||
|
|
||||||
if(avatarUrl && avatarUrl.length) newStyle.backgroundImage = `url('${ avatarUrl }')`;
|
if(!fit && avatarUrl && avatarUrl.length) newStyle.backgroundImage = `url('${ avatarUrl }')`;
|
||||||
|
|
||||||
|
if(headOnly && !fit)
|
||||||
|
{
|
||||||
|
newStyle.backgroundSize = '130px auto';
|
||||||
|
newStyle.backgroundPosition = '51% 40%';
|
||||||
|
newStyle.imageRendering = 'pixelated';
|
||||||
|
}
|
||||||
|
|
||||||
if(scale !== 1)
|
if(scale !== 1)
|
||||||
{
|
{
|
||||||
@@ -52,7 +68,7 @@ export const LayoutAvatarImageView: FC<LayoutAvatarImageViewProps> = props =>
|
|||||||
if(Object.keys(style).length) newStyle = { ...newStyle, ...style };
|
if(Object.keys(style).length) newStyle = { ...newStyle, ...style };
|
||||||
|
|
||||||
return newStyle;
|
return newStyle;
|
||||||
}, [ avatarUrl, scale, style ]);
|
}, [ avatarUrl, scale, style, headOnly, fit ]);
|
||||||
|
|
||||||
useEffect(() =>
|
useEffect(() =>
|
||||||
{
|
{
|
||||||
@@ -116,5 +132,17 @@ export const LayoutAvatarImageView: FC<LayoutAvatarImageViewProps> = props =>
|
|||||||
};
|
};
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
return <Base classNames={ getClassNames } style={ getStyle } { ...rest } />;
|
return (
|
||||||
|
<Base classNames={ getClassNames } style={ getStyle } { ...rest }>
|
||||||
|
{ fit && avatarUrl && avatarUrl.length > 0 && (
|
||||||
|
<img
|
||||||
|
src={ avatarUrl }
|
||||||
|
alt=""
|
||||||
|
draggable={ false }
|
||||||
|
className="absolute inset-0 w-full h-full object-contain"
|
||||||
|
style={ { imageRendering: 'pixelated', transform: 'translateY(-20%)' } }
|
||||||
|
/>
|
||||||
|
) }
|
||||||
|
</Base>
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -76,7 +76,7 @@ export const CatalogGridOfferView: FC<CatalogGridOfferViewProps> = props =>
|
|||||||
{ iconUrl && !(offer.product.productType === ProductTypeEnum.ROBOT) &&
|
{ iconUrl && !(offer.product.productType === ProductTypeEnum.ROBOT) &&
|
||||||
<div className="nitro-catalog-classic-grid-offer-icon" style={ { backgroundImage: `url(${ iconUrl })` } } /> }
|
<div className="nitro-catalog-classic-grid-offer-icon" style={ { backgroundImage: `url(${ iconUrl })` } } /> }
|
||||||
{ (offer.product.productType === ProductTypeEnum.ROBOT) &&
|
{ (offer.product.productType === ProductTypeEnum.ROBOT) &&
|
||||||
<LayoutAvatarImageView direction={ 3 } figure={ offer.product.extraParam } headOnly={ true } /> }
|
<LayoutAvatarImageView direction={ 2 } figure={ offer.product.extraParam } fit /> }
|
||||||
<div
|
<div
|
||||||
className={ `absolute top-0 right-0 z-10 p-0.5 cursor-pointer transition-opacity duration-100 ${ isFav ? 'opacity-100' : 'opacity-0 group-hover/tile:opacity-100' }` }
|
className={ `absolute top-0 right-0 z-10 p-0.5 cursor-pointer transition-opacity duration-100 ${ isFav ? 'opacity-100' : 'opacity-0 group-hover/tile:opacity-100' }` }
|
||||||
onClick={ e =>
|
onClick={ e =>
|
||||||
|
|||||||
@@ -88,7 +88,6 @@ export const CatalogLayoutDefaultView: FC<CatalogLayoutProps> = props =>
|
|||||||
</div>
|
</div>
|
||||||
</div> }
|
</div> }
|
||||||
|
|
||||||
{ /* Welcome/description card */ }
|
|
||||||
{ !currentOffer &&
|
{ !currentOffer &&
|
||||||
<div className="nitro-catalog-classic-welcome flex items-center gap-3">
|
<div className="nitro-catalog-classic-welcome flex items-center gap-3">
|
||||||
{ !!page.localization.getImage(1) &&
|
{ !!page.localization.getImage(1) &&
|
||||||
@@ -96,11 +95,10 @@ export const CatalogLayoutDefaultView: FC<CatalogLayoutProps> = props =>
|
|||||||
<Text className="text-[11px]! text-muted" dangerouslySetInnerHTML={ { __html: SanitizeHtml(page.localization.getText(0)) } } />
|
<Text className="text-[11px]! text-muted" dangerouslySetInnerHTML={ { __html: SanitizeHtml(page.localization.getText(0)) } } />
|
||||||
</div> }
|
</div> }
|
||||||
|
|
||||||
{ /* Item grid */ }
|
|
||||||
<div className="nitro-catalog-classic-grid-shell flex-1 overflow-auto min-h-0">
|
<div className="nitro-catalog-classic-grid-shell flex-1 overflow-auto min-h-0">
|
||||||
{ GetConfigurationValue('catalog.headers') &&
|
{ GetConfigurationValue('catalog.headers') &&
|
||||||
<CatalogHeaderView imageUrl={ currentPage.localization.getImage(0) } /> }
|
<CatalogHeaderView imageUrl={ currentPage.localization.getImage(0) } /> }
|
||||||
<CatalogItemGridWidgetView className="nitro-catalog-classic-grid" columnCount={ 7 } columnMinHeight={ 50 } columnMinWidth={ 50 } />
|
<CatalogItemGridWidgetView className="nitro-catalog-classic-grid" columnCount={ 7 } columnMinHeight={ currentPage.layoutCode === 'bots' ? 65 : 50 } columnMinWidth={ currentPage.layoutCode === 'bots' ? 65 : 50 } />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -38,8 +38,8 @@ export const InventoryBotItemView: FC<PropsWithChildren<{
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<InfiniteGrid.Item itemActive={ (selectedBot === botItem) } itemUnseen={ unseen } onDoubleClick={ onMouseEvent } onMouseDown={ onMouseEvent } onMouseOut={ onMouseEvent } onMouseUp={ onMouseEvent } { ...rest } className="*:[background-position-y:-32px]">
|
<InfiniteGrid.Item itemActive={ (selectedBot === botItem) } itemUnseen={ unseen } onDoubleClick={ onMouseEvent } onMouseDown={ onMouseEvent } onMouseOut={ onMouseEvent } onMouseUp={ onMouseEvent } { ...rest } className="aspect-[2/3]">
|
||||||
<LayoutAvatarImageView direction={ 3 } figure={ botItem.botData.figure } headOnly={ true } />
|
<LayoutAvatarImageView direction={ 2 } figure={ botItem.botData.figure } fit />
|
||||||
{ children }
|
{ children }
|
||||||
</InfiniteGrid.Item>
|
</InfiniteGrid.Item>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ export const InventoryBotView: FC<{
|
|||||||
<div className="grid h-full grid-cols-12 gap-2">
|
<div className="grid h-full grid-cols-12 gap-2">
|
||||||
<div className="flex flex-col col-span-7 gap-1 overflow-hidden">
|
<div className="flex flex-col col-span-7 gap-1 overflow-hidden">
|
||||||
<InfiniteGrid<IBotItem>
|
<InfiniteGrid<IBotItem>
|
||||||
columnCount={ 6 }
|
columnCount={ 4 }
|
||||||
itemRender={ item => <InventoryBotItemView botItem={ item } /> }
|
itemRender={ item => <InventoryBotItemView botItem={ item } /> }
|
||||||
items={ botItems } />
|
items={ botItems } />
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user