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>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{/* Items on Ground */}
|
{/* Items on Ground - Stable Sort */}
|
||||||
{location.items.length > 0 && (
|
{location.items.length > 0 && (
|
||||||
<div className="entity-section items-section">
|
<div className="entity-section items-section">
|
||||||
<h3>{t('location.itemsOnGround')}</h3>
|
<h3>{t('location.itemsOnGround')}</h3>
|
||||||
<div className="entity-list grid-view">
|
<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 isShaking = failedActionItemId == item.id;
|
||||||
const itemId = `item-${item.id}-${i}`;
|
const itemId = `item-${item.id}-${i}`;
|
||||||
|
|
||||||
@@ -394,7 +396,7 @@ function LocationView({
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
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)}
|
onClick={(e) => handleDropdownClick(e, itemId)}
|
||||||
>
|
>
|
||||||
<GameTooltip content={
|
<GameTooltip content={
|
||||||
@@ -496,8 +498,8 @@ function LocationView({
|
|||||||
|
|
||||||
{/* Corpse Loot Overlay Modal */}
|
{/* Corpse Loot Overlay Modal */}
|
||||||
{expandedCorpse && corpseDetails && corpseDetails.loot_items && (
|
{expandedCorpse && corpseDetails && corpseDetails.loot_items && (
|
||||||
<div className="corpse-loot-overlay">
|
<div className="corpse-loot-overlay" onClick={() => onSetExpandedCorpse(null)}>
|
||||||
<div className="corpse-loot-modal">
|
<div className="corpse-loot-modal" onClick={(e) => e.stopPropagation()}>
|
||||||
<div className="corpse-details-header">
|
<div className="corpse-details-header">
|
||||||
<h4>{t('location.lootableItems')}</h4>
|
<h4>{t('location.lootableItems')}</h4>
|
||||||
<button
|
<button
|
||||||
@@ -512,10 +514,28 @@ function LocationView({
|
|||||||
<div className="corpse-items-list">
|
<div className="corpse-items-list">
|
||||||
{corpseDetails.loot_items.map((item: any) => (
|
{corpseDetails.loot_items.map((item: any) => (
|
||||||
<div key={item.index} className={`corpse-item ${!item.can_loot ? 'locked' : ''}`}>
|
<div key={item.index} className={`corpse-item ${!item.can_loot ? 'locked' : ''}`}>
|
||||||
<div className="corpse-item-info">
|
{/* Item Image */}
|
||||||
<div className="corpse-item-name">
|
<div className="corpse-item-image">
|
||||||
{item.emoji} {getTranslatedText(item.item_name)}
|
{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>
|
||||||
|
|
||||||
|
<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">
|
<div className="corpse-item-qty">
|
||||||
{t('common.qty')}: {item.quantity_min}{item.quantity_min !== item.quantity_max ? `-${item.quantity_max}` : ''}
|
{t('common.qty')}: {item.quantity_min}{item.quantity_min !== item.quantity_max ? `-${item.quantity_max}` : ''}
|
||||||
</div>
|
</div>
|
||||||
@@ -525,6 +545,7 @@ function LocationView({
|
|||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<GameTooltip content={!item.can_loot ? `Requires ${getTranslatedText(item.required_tool_name)}` : 'Loot this item'}>
|
<GameTooltip content={!item.can_loot ? `Requires ${getTranslatedText(item.required_tool_name)}` : 'Loot this item'}>
|
||||||
<button
|
<button
|
||||||
className="corpse-item-loot-btn"
|
className="corpse-item-loot-btn"
|
||||||
|
|||||||
Reference in New Issue
Block a user