Refactor reward campaign list
All checks were successful
Deploy to Server / deploy (push) Successful in 26s

This commit is contained in:
Joakim Hellsén 2026-06-15 16:23:45 +02:00
commit 58d0ddeb43
Signed by: Joakim Hellsén
SSH key fingerprint: SHA256:/9h/CsExpFp+PRhsfA0xznFx2CGfTT5R/kpuFfUgEQk
3 changed files with 94 additions and 116 deletions

View file

@ -0,0 +1,65 @@
{% load image_tags %}
<article id="reward-campaign-{{ campaign.twitch_id }}"
style="display: flex;
gap: 1rem;
margin-bottom: 1rem;
align-items: flex-start">
<a href="{% url 'twitch:reward_campaign_detail' campaign.twitch_id %}"
style="flex-shrink: 0;
display: block;
line-height: 0">{% picture campaign.image_best_url alt="Image for "|add:campaign.name width=120 %}</a>
<div>
<h3 style="margin: 0;">
<a href="{% url 'twitch:reward_campaign_detail' campaign.twitch_id %}">
{% if campaign.brand %}
{{ campaign.brand }}: {{ campaign.name }}
{% else %}
{{ campaign.name }}
{% endif %}
</a>
</h3>
{% if campaign.starts_at <= now and campaign.ends_at >= now %}
<p style="margin: 0.25rem 0;">
<strong>Ends:</strong>
<time datetime="{{ campaign.ends_at|date:'c' }}"
title="{{ campaign.ends_at|date:'DATETIME_FORMAT' }}">
{{ campaign.ends_at|date:"M d, Y H:i" }} ({{ campaign.ends_at|timeuntil }} left)
</time>
</p>
{% elif campaign.starts_at > now %}
<p style="margin: 0.25rem 0;">
<strong>Starts:</strong>
<time datetime="{{ campaign.starts_at|date:'c' }}"
title="{{ campaign.starts_at|date:'DATETIME_FORMAT' }}">
{{ campaign.starts_at|date:"M d, Y H:i" }} (in {{ campaign.starts_at|timeuntil }})
</time>
</p>
{% else %}
<p style="margin: 0.25rem 0;">
<strong>Ended:</strong>
<time datetime="{{ campaign.ends_at|date:'c' }}"
title="{{ campaign.ends_at|date:'DATETIME_FORMAT' }}">
{{ campaign.ends_at|date:"M d, Y H:i" }} ({{ campaign.ends_at|timesince }} ago)
</time>
</p>
{% endif %}
{% if campaign.game %}
<p style="margin: 0.25rem 0;">
<strong>Game:</strong>
<a href="{% url 'twitch:game_detail' campaign.game.twitch_id %}">{{ campaign.game.display_name }}</a>
</p>
{% elif campaign.is_sitewide %}
<p style="margin: 0.25rem 0;">
<strong>Type:</strong> Site-wide reward campaign
</p>
{% else %}
<p style="margin: 0.25rem 0;">
<strong>Type:</strong>
<a href="{% url 'twitch:game_less_rewards' %}">No game assigned</a>
</p>
{% endif %}
{% if campaign.summary %}
<p style="margin: 0.5rem 0 0 0;">{{ campaign.summary }}</p>
{% endif %}
</div>
</article>

View file

@ -1,5 +1,5 @@
{% extends "base.html" %} {% extends "base.html" %}
{% load static %} {% load image_tags %}
{% block title %} {% block title %}
Reward Campaigns Reward Campaigns
{% endblock title %} {% endblock title %}
@ -18,17 +18,15 @@
href="{% url 'core:reward_campaign_feed_discord' %}" /> href="{% url 'core:reward_campaign_feed_discord' %}" />
{% endblock extra_head %} {% endblock extra_head %}
{% block content %} {% block content %}
<h1>List of Twitch Reward Campaigns</h1> <h1>Twitch Reward Campaigns</h1>
<!-- Add breadcrumbs -->
<div> <div>
<a href="{% url 'twitch:dashboard' %}">Twitch</a> > Reward Campaigns <a href="{% url 'twitch:dashboard' %}">Twitch</a> &gt; Reward Campaigns
</div> </div>
<p> <p>
Data is scraped from <a href="https://github.com/SunkwiBOT/twitch-drops-api" Data is scraped from <a href="https://github.com/SunkwiBOT/twitch-drops-api"
target="_blank" target="_blank"
rel="noopener">SunkwiBOT/twitch-drops-api</a> every 15 minutes. rel="noopener">SunkwiBOT/twitch-drops-api</a> every 15 minutes.
</p> </p>
<!-- RSS Feeds -->
<div> <div>
<div> <div>
<a href="{% url 'core:docs_rss' %}" title="RSS feed documentation">[explain]</a> <a href="{% url 'core:docs_rss' %}" title="RSS feed documentation">[explain]</a>
@ -45,116 +43,29 @@
</div> </div>
</div> </div>
{% if reward_campaigns %} {% if reward_campaigns %}
{% with active_campaigns=reward_campaigns|dictsortreversed:"ends_at" %} {% with sorted_campaigns=reward_campaigns|dictsortreversed:"ends_at" %}
<h5>Active Reward Campaigns</h5> {# Active campaigns #}
<table> <h2>Active Reward Campaigns</h2>
<tbody> {% for campaign in sorted_campaigns %}
{% for campaign in active_campaigns %} {% if campaign.starts_at <= now and campaign.ends_at >= now %}
{% if campaign.starts_at <= now and campaign.ends_at >= now %} {% include "twitch/includes/reward_campaign_card.html" with campaign=campaign %}
<tr> {% endif %}
<td> {% endfor %}
<a href="{% url 'twitch:reward_campaign_detail' campaign.twitch_id %}"> {# Upcoming campaigns #}
{% if campaign.brand %} <h2>Upcoming Reward Campaigns</h2>
{{ campaign.brand }}: {{ campaign.name }} {% for campaign in sorted_campaigns %}
{% else %} {% if campaign.starts_at > now %}
{{ campaign.name }} {% include "twitch/includes/reward_campaign_card.html" with campaign=campaign %}
{% endif %} {% endif %}
</a> {% endfor %}
{% if campaign.summary %} {# Past campaigns #}
<br /> <h2>Past Reward Campaigns</h2>
<small>{{ campaign.summary }}</small> {% for campaign in sorted_campaigns %}
{% endif %} {% if campaign.ends_at < now %}
</td> {% include "twitch/includes/reward_campaign_card.html" with campaign=campaign %}
<td> {% endif %}
{% if campaign.game %} {% endfor %}
<a href="{% url 'twitch:game_detail' campaign.game.twitch_id %}">{{ campaign.game.display_name }}</a>
{% elif campaign.is_sitewide %}
<a href="{% url 'twitch:sitewide_rewards' %}">Site-wide</a>
{% else %}
<a href="{% url 'twitch:game_less_rewards' %}">[no game]</a>
{% endif %}
</td>
<td>
<span title="{{ campaign.ends_at|date:'M d, Y H:i' }}">Ends in {{ campaign.ends_at|timeuntil }}</span>
</td>
</tr>
{% endif %}
{% endfor %}
</tbody>
</table>
<h5>Upcoming Reward Campaigns</h5>
<table>
<tbody>
{% for campaign in active_campaigns %}
{% if campaign.starts_at > now %}
<tr>
<td>
<a href="{% url 'twitch:reward_campaign_detail' campaign.twitch_id %}">
{% if campaign.brand %}
{{ campaign.brand }}: {{ campaign.name }}
{% else %}
{{ campaign.name }}
{% endif %}
</a>
{% if campaign.summary %}
<br />
<small>{{ campaign.summary }}</small>
{% endif %}
</td>
<td>
{% if campaign.game %}
<a href="{% url 'twitch:game_detail' campaign.game.twitch_id %}">{{ campaign.game.display_name }}</a>
{% elif campaign.is_sitewide %}
<a href="{% url 'twitch:sitewide_rewards' %}">Site-wide</a>
{% else %}
<a href="{% url 'twitch:game_less_rewards' %}">[no game]</a>
{% endif %}
</td>
<td>
<span title="Starts on {{ campaign.starts_at|date:'M d, Y H:i' }}">Starts in {{ campaign.starts_at|timeuntil }}</span>
</td>
</tr>
{% endif %}
{% endfor %}
</tbody>
</table>
{% endwith %} {% endwith %}
<h5>Past Reward Campaigns</h5>
<table>
<tbody>
{% for campaign in reward_campaigns %}
{% if campaign.ends_at < now %}
<tr>
<td>
<a href="{% url 'twitch:reward_campaign_detail' campaign.twitch_id %}">
{% if campaign.brand %}
{{ campaign.brand }}: {{ campaign.name }}
{% else %}
{{ campaign.name }}
{% endif %}
</a>
{% if campaign.summary %}
<br />
<small>{{ campaign.summary }}</small>
{% endif %}
</td>
<td>
{% if campaign.game %}
<a href="{% url 'twitch:game_detail' campaign.game.twitch_id %}">{{ campaign.game.display_name }}</a>
{% elif campaign.is_sitewide %}
<a href="{% url 'twitch:sitewide_rewards' %}">Site-wide</a>
{% else %}
<a href="{% url 'twitch:game_less_rewards' %}">[no game]</a>
{% endif %}
</td>
<td>
<span title="Ended on {{ campaign.ends_at|date:'M d, Y H:i' }}">{{ campaign.ends_at|timesince }} ago</span>
</td>
</tr>
{% endif %}
{% endfor %}
</tbody>
</table>
{% else %} {% else %}
<p>No reward campaigns found.</p> <p>No reward campaigns found.</p>
{% endif %} {% endif %}

View file

@ -2164,7 +2164,8 @@ class SitewideRewardCampaignAtomFeed(TTVDropsAtomBaseFeed, SitewideRewardCampaig
class SitewideRewardCampaignDiscordFeed( class SitewideRewardCampaignDiscordFeed(
TTVDropsAtomBaseFeed, SitewideRewardCampaignFeed TTVDropsAtomBaseFeed,
SitewideRewardCampaignFeed,
): ):
"""Discord feed for site-wide reward campaigns with Discord relative timestamps.""" """Discord feed for site-wide reward campaigns with Discord relative timestamps."""
@ -2409,7 +2410,8 @@ class GameLessRewardCampaignAtomFeed(TTVDropsAtomBaseFeed, GameLessRewardCampaig
class GameLessRewardCampaignDiscordFeed( class GameLessRewardCampaignDiscordFeed(
TTVDropsAtomBaseFeed, GameLessRewardCampaignFeed TTVDropsAtomBaseFeed,
GameLessRewardCampaignFeed,
): ):
"""Discord feed for reward campaigns with no game linked, with Discord timestamps.""" """Discord feed for reward campaigns with no game linked, with Discord timestamps."""