Fix unending: shelf status, not category
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful

Unending belongs in STATUS_CHOICES alongside completed/abandoned.
Adds an Unending shelf tab and an ∞ button on active game cards.
Reverts the incorrect category addition from the previous commit.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-01 23:32:09 +03:00
parent b765067c5b
commit 2e0ca22dd9
5 changed files with 19 additions and 17 deletions

View File

@@ -10,15 +10,15 @@ class Migration(migrations.Migration):
operations = [ operations = [
migrations.AlterField( migrations.AlterField(
model_name='item', model_name='item',
name='category', name='status',
field=models.CharField( field=models.CharField(
choices=[ choices=[
('games', 'Games'), ('active', 'Active'),
('books', 'Books'), ('completed', 'Completed'),
('films', 'Films'), ('abandoned', 'Abandoned'),
('unending', 'Unending'), ('unending', 'Unending'),
('other', 'Other'),
], ],
default='active',
max_length=10, max_length=10,
), ),
), ),

View File

@@ -6,23 +6,23 @@ class Item(models.Model):
GAMES = 'games' GAMES = 'games'
BOOKS = 'books' BOOKS = 'books'
FILMS = 'films' FILMS = 'films'
UNENDING = 'unending'
OTHER = 'other' OTHER = 'other'
CATEGORY_CHOICES = [ CATEGORY_CHOICES = [
(GAMES, 'Games'), (GAMES, 'Games'),
(BOOKS, 'Books'), (BOOKS, 'Books'),
(FILMS, 'Films'), (FILMS, 'Films'),
(UNENDING, 'Unending'),
(OTHER, 'Other'), (OTHER, 'Other'),
] ]
ACTIVE = 'active' ACTIVE = 'active'
COMPLETED = 'completed' COMPLETED = 'completed'
ABANDONED = 'abandoned' ABANDONED = 'abandoned'
UNENDING = 'unending'
STATUS_CHOICES = [ STATUS_CHOICES = [
(ACTIVE, 'Active'), (ACTIVE, 'Active'),
(COMPLETED, 'Completed'), (COMPLETED, 'Completed'),
(ABANDONED, 'Abandoned'), (ABANDONED, 'Abandoned'),
(UNENDING, 'Unending'),
] ]
user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='items', null=True) user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='items', null=True)

View File

@@ -252,9 +252,7 @@
function updateSections() { function updateSections() {
document.querySelectorAll('.cat-section').forEach(el => el.style.display = 'none'); document.querySelectorAll('.cat-section').forEach(el => el.style.display = 'none');
const cat = catSelect.value; const sec = document.getElementById('section-' + catSelect.value);
const secId = cat === 'unending' ? 'section-games' : 'section-' + cat;
const sec = document.getElementById(secId);
if (sec) sec.style.display = 'block'; if (sec) sec.style.display = 'block';
} }

View File

@@ -120,7 +120,6 @@
.badge-games { background: #3b2f6a; color: #a78bfa; } .badge-games { background: #3b2f6a; color: #a78bfa; }
.badge-books { background: #064e3b; color: #34d399; } .badge-books { background: #064e3b; color: #34d399; }
.badge-films { background: #431407; color: #fb923c; } .badge-films { background: #431407; color: #fb923c; }
.badge-unending { background: #0c3a52; color: #38bdf8; }
.badge-other { background: #1e293b; color: #94a3b8; } .badge-other { background: #1e293b; color: #94a3b8; }
.star { color: #fbbf24; font-size: 0.9rem; margin-left: auto; } .star { color: #fbbf24; font-size: 0.9rem; margin-left: auto; }
@@ -184,6 +183,7 @@
<a href="?sort={{ sort }}" class="tab {% if shelf == 'active' %}active{% endif %}">Active</a> <a href="?sort={{ sort }}" class="tab {% if shelf == 'active' %}active{% endif %}">Active</a>
<a href="?shelf=completed&sort={{ sort }}" class="tab {% if shelf == 'completed' %}active{% endif %}">Completed</a> <a href="?shelf=completed&sort={{ sort }}" class="tab {% if shelf == 'completed' %}active{% endif %}">Completed</a>
<a href="?shelf=abandoned&sort={{ sort }}" class="tab {% if shelf == 'abandoned' %}active{% endif %}">Abandoned</a> <a href="?shelf=abandoned&sort={{ sort }}" class="tab {% if shelf == 'abandoned' %}active{% endif %}">Abandoned</a>
<a href="?shelf=unending&sort={{ sort }}" class="tab {% if shelf == 'unending' %}active{% endif %}">Unending</a>
{% if shelf == 'active' %} {% if shelf == 'active' %}
<span class="tab-sep"></span> <span class="tab-sep"></span>
<a href="?sort={{ sort }}" class="tab {% if not category %}active{% endif %}">All</a> <a href="?sort={{ sort }}" class="tab {% if not category %}active{% endif %}">All</a>
@@ -234,10 +234,6 @@
{% if item.pages_read is not None %} {% if item.pages_read is not None %}
{{ item.pages_read }} pages{% if item.total_pages %} / {{ item.total_pages }} total{% endif %} {{ item.pages_read }} pages{% if item.total_pages %} / {{ item.total_pages }} total{% endif %}
{% endif %} {% endif %}
{% elif item.category == 'unending' %}
{% if item.hours_played is not None %}
{{ item.hours_played|floatformat:1 }}h played
{% endif %}
{% elif item.category == 'films' %} {% elif item.category == 'films' %}
{% if item.watched %}&#10003; Watched{% else %}&#9675; Not watched{% endif %}{% if item.duration_minutes %} &middot; {{ item.duration_minutes }} min{% endif %} {% if item.watched %}&#10003; Watched{% else %}&#9675; Not watched{% endif %}{% if item.duration_minutes %} &middot; {{ item.duration_minutes }} min{% endif %}
{% endif %} {% endif %}
@@ -252,6 +248,14 @@
<input type="hidden" name="next" value="{{ request.get_full_path }}"> <input type="hidden" name="next" value="{{ request.get_full_path }}">
<button type="submit" class="btn btn-done">Done</button> <button type="submit" class="btn btn-done">Done</button>
</form> </form>
{% if item.category == 'games' %}
<form method="post" action="{% url 'backlogger:set_status' item.pk %}">
{% csrf_token %}
<input type="hidden" name="status" value="unending">
<input type="hidden" name="next" value="{{ request.get_full_path }}">
<button type="submit" class="btn btn-sm btn-outline" style="color:#38bdf8;border-color:#38bdf8" title="Unending"></button>
</form>
{% endif %}
<form method="post" action="{% url 'backlogger:set_status' item.pk %}"> <form method="post" action="{% url 'backlogger:set_status' item.pk %}">
{% csrf_token %} {% csrf_token %}
<input type="hidden" name="status" value="abandoned"> <input type="hidden" name="status" value="abandoned">

View File

@@ -36,7 +36,7 @@ def item_list(request):
category = request.GET.get('category', '') category = request.GET.get('category', '')
sort = request.GET.get('sort', 'fav') sort = request.GET.get('sort', 'fav')
shelf = request.GET.get('shelf', Item.ACTIVE) shelf = request.GET.get('shelf', Item.ACTIVE)
if shelf not in (Item.ACTIVE, Item.COMPLETED, Item.ABANDONED): if shelf not in (Item.ACTIVE, Item.COMPLETED, Item.ABANDONED, Item.UNENDING):
shelf = Item.ACTIVE shelf = Item.ACTIVE
items = Item.objects.filter(user=request.user, status=shelf) items = Item.objects.filter(user=request.user, status=shelf)
@@ -88,7 +88,7 @@ def item_set_status(request, pk):
if request.method == 'POST': if request.method == 'POST':
item = get_object_or_404(Item, pk=pk, user=request.user) item = get_object_or_404(Item, pk=pk, user=request.user)
new_status = request.POST.get('status') new_status = request.POST.get('status')
if new_status in (Item.ACTIVE, Item.COMPLETED, Item.ABANDONED): if new_status in (Item.ACTIVE, Item.COMPLETED, Item.ABANDONED, Item.UNENDING):
item.status = new_status item.status = new_status
item.save(update_fields=['status', 'updated_at']) item.save(update_fields=['status', 'updated_at'])
next_url = request.POST.get('next') or reverse('backlogger:list') next_url = request.POST.get('next') or reverse('backlogger:list')