fix(ui): stable sort for ground items, improved loot modal (images/desc, outside click)
This commit is contained in:
@@ -360,12 +360,14 @@ function LocationView({
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Items on Ground */}
|
||||
{/* Items on Ground - Stable Sort */}
|
||||
{location.items.length > 0 && (
|
||||
<div className="entity-section items-section">
|
||||
<h3>{t('location.itemsOnGround')}</h3>
|
||||
<div className="entity-list grid-view">
|
||||
{location.items.map((item: any, i: number) => {
|
||||
{[...location.items]
|
||||
.sort((a: any, b: any) => (a.id || 0) - (b.id || 0))
|
||||
.map((item: any, i: number) => {
|
||||
const isShaking = failedActionItemId == item.id;
|
||||
const itemId = `item-${item.id}-${i}`;
|
||||
|
||||
@@ -394,7 +396,7 @@ function LocationView({
|
||||
};
|
||||
|
||||
return (
|
||||
<div key={i} className={`entity-card item-card ${isShaking ? 'shake' : ''} grid-card`}
|
||||
<div key={item.id} className={`entity-card item-card ${isShaking ? 'shake' : ''} grid-card`}
|
||||
onClick={(e) => handleDropdownClick(e, itemId)}
|
||||
>
|
||||
<GameTooltip content={
|
||||
@@ -496,8 +498,8 @@ function LocationView({
|
||||
|
||||
{/* Corpse Loot Overlay Modal */}
|
||||
{expandedCorpse && corpseDetails && corpseDetails.loot_items && (
|
||||
<div className="corpse-loot-overlay">
|
||||
<div className="corpse-loot-modal">
|
||||
<div className="corpse-loot-overlay" onClick={() => onSetExpandedCorpse(null)}>
|
||||
<div className="corpse-loot-modal" onClick={(e) => e.stopPropagation()}>
|
||||
<div className="corpse-details-header">
|
||||
<h4>{t('location.lootableItems')}</h4>
|
||||
<button
|
||||
@@ -512,10 +514,28 @@ function LocationView({
|
||||
<div className="corpse-items-list">
|
||||
{corpseDetails.loot_items.map((item: any) => (
|
||||
<div key={item.index} className={`corpse-item ${!item.can_loot ? 'locked' : ''}`}>
|
||||
<div className="corpse-item-info">
|
||||
<div className="corpse-item-name">
|
||||
{item.emoji} {getTranslatedText(item.item_name)}
|
||||
{/* Item Image */}
|
||||
<div className="corpse-item-image">
|
||||
{item.image_path ? (
|
||||
<img
|
||||
src={getAssetPath(item.image_path)}
|
||||
alt={item.item_name}
|
||||
className="item-img-thumb"
|
||||
style={{ width: '40px', height: '40px', objectFit: 'contain', marginRight: '10px' }}
|
||||
onError={(e) => {
|
||||
(e.target as HTMLImageElement).style.display = 'none';
|
||||
// Fallback emoji next to it will show if image fails?
|
||||
// Current logic doesn't have fallback emoji element sibling, just keeping it simple.
|
||||
}}
|
||||
/>
|
||||
) : <span style={{ fontSize: '2rem', marginRight: '10px' }}>{item.emoji || '📦'}</span>}
|
||||
</div>
|
||||
|
||||
<div className="corpse-item-info" style={{ flex: 1 }}>
|
||||
<div className="corpse-item-name">
|
||||
{getTranslatedText(item.item_name)}
|
||||
</div>
|
||||
{item.description && <div className="corpse-item-desc" style={{ fontSize: '0.75rem', color: '#a0aec0' }}>{getTranslatedText(item.description)}</div>}
|
||||
<div className="corpse-item-qty">
|
||||
{t('common.qty')}: {item.quantity_min}{item.quantity_min !== item.quantity_max ? `-${item.quantity_max}` : ''}
|
||||
</div>
|
||||
@@ -525,6 +545,7 @@ function LocationView({
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<GameTooltip content={!item.can_loot ? `Requires ${getTranslatedText(item.required_tool_name)}` : 'Loot this item'}>
|
||||
<button
|
||||
className="corpse-item-loot-btn"
|
||||
|
||||
Reference in New Issue
Block a user