mirror of
https://github.com/rangermix/TwitchDropsMiner.git
synced 2026-05-30 17:09:36 +00:00
feat: display benefits as individual lines with icon, name, and type
Enhanced the inventory tab to show each benefit on its own line instead of an icon grid. Each benefit now displays with: - Icon (40x40px) on the left - Benefit name and type on the right in format: "Name (TYPE)" Changes: - Backend: Send full benefit data (name, type, image_url) instead of just URLs - Frontend: Render benefits as vertical list of horizontal lines - CSS: Add new styles for benefit items (.benefit-item, .benefit-icon, .benefit-info) - Removed: Icon grid layout (chunks of 3) and rewards text field 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -3,6 +3,7 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import asyncio
|
||||
import logging
|
||||
from typing import TYPE_CHECKING, Any
|
||||
|
||||
|
||||
@@ -12,6 +13,9 @@ if TYPE_CHECKING:
|
||||
from src.web.managers.cache import ImageCache
|
||||
|
||||
|
||||
logger = logging.getLogger("TwitchDrops")
|
||||
|
||||
|
||||
class InventoryManager:
|
||||
"""Manages drop campaign inventory display in the web interface.
|
||||
|
||||
@@ -41,6 +45,16 @@ class InventoryManager:
|
||||
|
||||
drops_data = []
|
||||
for drop in campaign.drops:
|
||||
# Collect full benefit data (filter out benefits without images)
|
||||
benefits_data = [
|
||||
{
|
||||
"name": benefit.name,
|
||||
"type": benefit.type.name,
|
||||
"image_url": str(benefit.image_url),
|
||||
}
|
||||
for benefit in drop.benefits
|
||||
if benefit.image_url
|
||||
]
|
||||
drops_data.append(
|
||||
{
|
||||
"id": drop.id,
|
||||
@@ -50,7 +64,7 @@ class InventoryManager:
|
||||
"progress": drop.progress,
|
||||
"is_claimed": drop.is_claimed,
|
||||
"can_claim": drop.can_claim,
|
||||
"rewards": drop.rewards_text(),
|
||||
"benefits": benefits_data,
|
||||
"starts_at": drop.starts_at.isoformat(),
|
||||
"ends_at": drop.ends_at.isoformat(),
|
||||
}
|
||||
|
||||
@@ -494,14 +494,36 @@ function renderInventory() {
|
||||
}
|
||||
|
||||
const claimedText = t.gui?.inventory?.status?.claimed || 'Claimed';
|
||||
const dropsHtml = campaign.drops.map(drop => `
|
||||
<div class="drop-item ${drop.is_claimed ? 'claimed' : ''} ${drop.can_claim ? 'active' : ''}">
|
||||
<div><strong>${drop.name}</strong></div>
|
||||
<div>${drop.rewards}</div>
|
||||
<div>${drop.current_minutes} / ${drop.required_minutes} minutes (${Math.round(drop.progress * 100)}%)</div>
|
||||
${drop.is_claimed ? `<div>✓ ${claimedText}</div>` : ''}
|
||||
</div>
|
||||
`).join('');
|
||||
const dropsHtml = campaign.drops.map(drop => {
|
||||
// Generate HTML for each benefit as its own line
|
||||
let benefitsHtml = '';
|
||||
if (drop.benefits && drop.benefits.length > 0) {
|
||||
benefitsHtml = drop.benefits.map(benefit =>
|
||||
`<div class="benefit-item">
|
||||
<img src="${benefit.image_url}" alt="${benefit.name}" class="benefit-icon" onerror="this.style.display='none'">
|
||||
<div class="benefit-info">
|
||||
<span class="benefit-name">${benefit.name}</span>
|
||||
<span class="benefit-type">(${benefit.type})</span>
|
||||
</div>
|
||||
</div>`
|
||||
).join('');
|
||||
}
|
||||
|
||||
return `
|
||||
<div class="drop-item ${drop.is_claimed ? 'claimed' : ''} ${drop.can_claim ? 'active' : ''}">
|
||||
<div class="drop-item-header">
|
||||
<div class="drop-item-info">
|
||||
<div><strong>${drop.name}</strong></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="benefits-list">
|
||||
${benefitsHtml}
|
||||
</div>
|
||||
<div>${drop.current_minutes} / ${drop.required_minutes} minutes (${Math.round(drop.progress * 100)}%)</div>
|
||||
${drop.is_claimed ? `<div>✓ ${claimedText}</div>` : ''}
|
||||
</div>
|
||||
`;
|
||||
}).join('');
|
||||
|
||||
// Make campaign name clickable if link_url is available
|
||||
const campaignNameHtml = campaign.link_url
|
||||
|
||||
@@ -500,6 +500,66 @@ header h1 {
|
||||
border-left-color: var(--accent-color);
|
||||
}
|
||||
|
||||
.drop-item-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.drop-item-info {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.benefits-list {
|
||||
margin-top: 8px;
|
||||
margin-bottom: 8px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.benefit-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
padding: 8px;
|
||||
background: var(--bg-panel);
|
||||
border-radius: 4px;
|
||||
border: 1px solid var(--border-color);
|
||||
}
|
||||
|
||||
.benefit-icon {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
border-radius: 4px;
|
||||
object-fit: cover;
|
||||
border: 2px solid var(--border-color);
|
||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.benefit-info {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.benefit-name {
|
||||
font-weight: 500;
|
||||
font-size: 14px;
|
||||
color: var(--text-primary);
|
||||
}
|
||||
|
||||
.benefit-type {
|
||||
font-size: 12px;
|
||||
color: var(--text-secondary);
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
/* Settings */
|
||||
.settings-container {
|
||||
max-width: 800px;
|
||||
|
||||
Reference in New Issue
Block a user