Made the feed config page less shit

This commit is contained in:
Joakim Hellsén 2026-07-18 06:25:29 +02:00
commit 59d9062ded
Signed by: Joakim Hellsén
SSH key fingerprint: SHA256:/9h/CsExpFp+PRhsfA0xznFx2CGfTT5R/kpuFfUgEQk

View file

@ -103,7 +103,7 @@
{% elif delivery_mode == "screenshot" %}
<li>Screenshot layout: {{ screenshot_layout }}.</li>
{% endif %}
<li>Webhook text is truncated to {{ webhook_text_length_limit }} characters.</li>
<li>Webhook text</li> is truncated to {{ webhook_text_length_limit }} characters.</li>
<li>
Filters:
{% if has_blacklist_filters and has_whitelist_filters %}
@ -161,86 +161,93 @@
<button class="btn btn-danger btn-sm" name="feed_url" value="{{ feed.url }}">Pause</button>
</form>
{% endif %}
</div>
</section>
<div class="row row-cols-1 row-cols-lg-2 g-3 mt-2">
<div class="col">
<div class="card border border-secondary shadow-sm h-100 rounded-0">
<div class="card-header bg-transparent border-secondary text-muted text-uppercase small fw-semibold">
Delivery Settings
</div>
<div class="card-body">
<section class="mb-3">
<h4 class="h6 text-muted mb-2">Delivery Mode</h4>
<p class="text-muted small mb-2">
Choose between:<br>
Embed: a Discord embed with title, description, and images.<br>
{% if not "youtube.com/feeds/videos.xml" in feed.url %}
{% if delivery_mode == "embed" %}
<form action="/use_text" method="post" class="d-inline">
<button class="btn btn-outline-light btn-sm"
name="feed_url"
value="{{ feed.url }}">Send text message instead of embed</button>
</form>
{% elif delivery_mode == "screenshot" %}
<form action="/use_text" method="post" class="d-inline">
<button class="btn btn-outline-light btn-sm"
name="feed_url"
value="{{ feed.url }}">Send text message instead of screenshot</button>
</form>
{% else %}
Screenshot: full-page screenshot of the entry link.<br>
{% endif %}
Text: plain message.
</p>
<div class="d-flex" role="group" aria-label="Delivery mode">
{% if delivery_mode != "embed" %}
<form action="/use_embed" method="post" class="d-inline">
<button class="btn btn-outline-light btn-sm"
style="border-top-right-radius: 0; border-bottom-right-radius: 0;"
name="feed_url"
value="{{ feed.url }}">Send embed instead of text message</button>
value="{{ feed.url }}">Embed</button>
</form>
{% else %}
<span class="btn btn-primary btn-sm disabled"
style="border-top-right-radius: 0; border-bottom-right-radius: 0;">Embed</span>
{% endif %}
{% if not "youtube.com/feeds/videos.xml" in feed.url %}
{% if delivery_mode != "screenshot" %}
<form action="/use_screenshot" method="post" class="d-inline">
<button class="btn btn-outline-light btn-sm rounded-0"
name="feed_url"
value="{{ feed.url }}">Screenshot</button>
</form>
{% else %}
<span class="btn btn-primary btn-sm disabled rounded-0">Screenshot</span>
{% endif %}
{% endif %}
{% if delivery_mode != "text" %}
<form action="/use_text" method="post" class="d-inline">
<button class="btn btn-outline-light btn-sm"
style="border-top-left-radius: 0; border-bottom-left-radius: 0;"
name="feed_url"
value="{{ feed.url }}">Text</button>
</form>
{% else %}
<span class="btn btn-primary btn-sm disabled"
style="border-top-left-radius: 0; border-bottom-left-radius: 0;">Text</span>
{% endif %}
</div>
</section>
{% if not "youtube.com/feeds/videos.xml" in feed.url %}
<section class="mt-4 pt-3 border-top border-secondary-subtle">
<div class="d-flex flex-wrap align-items-center justify-content-between gap-2 mb-2">
<h3 class="h6 text-uppercase text-muted mb-0">Screenshot Delivery</h3>
<span class="badge {{ 'bg-info' if delivery_mode == 'screenshot' else 'bg-secondary' }}">
{% if delivery_mode == "screenshot" %}
Active:
{% if screenshot_layout == "mobile" %}
Mobile
{% else %}
Desktop
{% endif %}
{% else %}
Inactive
{% endif %}
</span>
</div>
<p class="text-muted mb-3">
Screenshot delivery sends a full-page screenshot of the entry link instead of the normal
embed or text message.
</p>
{% if delivery_mode == "screenshot" and not "youtube.com/feeds/videos.xml" in feed.url %}
<hr class="border-secondary" />
<section class="mb-3">
<h4 class="h6 text-muted mb-2">Screenshot Layout</h4>
<div class="d-flex flex-wrap gap-2">
{% if delivery_mode != "screenshot" %}
<form action="/use_screenshot" method="post" class="d-inline">
<button class="btn btn-outline-light btn-sm"
name="feed_url"
value="{{ feed.url }}">Use screenshot delivery</button>
</form>
{% else %}
<form action="/use_embed" method="post" class="d-inline">
<button class="btn btn-outline-light btn-sm"
name="feed_url"
value="{{ feed.url }}">Disable screenshot delivery</button>
</form>
{% if screenshot_layout == "mobile" %}
<span class="btn btn-primary btn-sm disabled">Mobile</span>
<form action="/use_screenshot_desktop" method="post" class="d-inline">
<button class="btn btn-outline-light btn-sm"
name="feed_url"
value="{{ feed.url }}">Use desktop screenshot layout</button>
value="{{ feed.url }}">Desktop</button>
</form>
{% else %}
<form action="/use_screenshot_mobile" method="post" class="d-inline">
<button class="btn btn-outline-secondary btn-sm"
<button class="btn btn-outline-light btn-sm"
name="feed_url"
value="{{ feed.url }}">Use mobile screenshot layout</button>
value="{{ feed.url }}">Mobile</button>
</form>
{% endif %}
<span class="btn btn-primary btn-sm disabled">Desktop</span>
{% endif %}
</div>
<div class="mt-2 screenshot-requirement">
Screenshot mode requires Chromium to be installed for Playwright. Run
<code>uv run playwright install chromium</code> once on this machine.
<div class="mt-2 small text-muted">
Requires Chromium for Playwright. Run
<code class="text-light">uv run playwright install chromium</code> once.
</div>
</section>
<section class="mt-4 pt-3 border-top border-secondary-subtle">
{% endif %}
{% if not "youtube.com/feeds/videos.xml" in feed.url %}
<hr class="border-secondary" />
<section class="mb-3">
<div class="d-flex flex-wrap align-items-center justify-content-between gap-2 mb-2">
<h3 class="h6 text-uppercase text-muted mb-0">Image Delivery</h3>
<h4 class="h6 text-muted mb-0">Image Delivery</h4>
<span class="badge {{ 'bg-info' if media_gallery_image_limit < max_media_gallery_items else 'bg-secondary' }}">
{% if media_gallery_image_limit == 0 %}
No images
@ -251,10 +258,8 @@
{% endif %}
</span>
</div>
<p id="imageDeliveryHelp" class="text-muted mb-3">
Choose 0 to send no entry images, 1 for the first image only,
or up to {{ max_media_gallery_items }} for a Discord media gallery.
This only affects embed delivery.
<p id="imageDeliveryHelp" class="text-muted small mb-2">
How many images to include per entry. Only applies to embed mode.
</p>
<form action="/set_feed_media_gallery_image_limit"
method="post"
@ -278,7 +283,7 @@
oninput="this.form.elements.image_limit_value.value = this.value" />
<div class="d-flex justify-content-between text-muted small">
<span>0</span>
<span>{{ max_media_gallery_items }}</span>
</span> <span>{{ max_media_gallery_items }}</span>
</div>
</div>
<button class="btn btn-outline-light btn-sm" type="submit">Save image limit</button>
@ -286,14 +291,15 @@
</form>
</section>
{% endif %}
<section class="mt-4 pt-3 border-top border-secondary-subtle">
<hr class="border-secondary" />
<section>
<div class="d-flex flex-wrap align-items-center justify-content-between gap-2 mb-2">
<h3 class="h6 text-uppercase text-muted mb-0">Text Delivery</h3>
<h4 class="h6 text-muted mb-0">Text Delivery</h4>
<span class="badge {{ 'bg-info' if webhook_text_length_limit < max_webhook_text_length_limit else 'bg-secondary' }}">
Max {{ webhook_text_length_limit }} characters
</span>
</div>
<p id="textDeliveryHelp" class="text-muted mb-3">
<p id="textDeliveryHelp" class="text-muted small mb-2">
Limit message length. Text mode allows values up to 4000 characters. Embeds are capped at 2000 characters.
</p>
<form action="/set_feed_webhook_text_length_limit"
@ -318,35 +324,20 @@
</div>
</form>
</section>
<section class="mt-4 pt-3 border-top border-secondary-subtle">
<h3 class="h6 text-uppercase text-muted mb-3">Customization</h3>
<div class="d-flex flex-wrap gap-2">
<a class="btn btn-sm btn-outline-light"
href="/whitelist?feed_url={{ feed.url|encode_url }}">Whitelist</a>
<a class="btn btn-sm btn-outline-light"
href="/blacklist?feed_url={{ feed.url|encode_url }}">Blacklist</a>
<a class="btn btn-sm btn-outline-light"
href="/custom?feed_url={{ feed.url|encode_url }}">
Customize message
{% if delivery_mode == "text" %}(Currently active){% endif %}
</a>
{% if not "youtube.com/feeds/videos.xml" in feed.url %}
<a class="btn btn-sm btn-outline-light"
href="/embed?feed_url={{ feed.url|encode_url }}">
Customize embed
{% if delivery_mode == "embed" %}(Currently active){% endif %}
</a>
{% endif %}
</div>
{% if is_steam_feed %}
<div class="form-text mt-2">Steam feeds can enable thumbnails in embed settings.</div>
{% endif %}
</section>
<section class="mt-4 pt-3 border-top border-secondary-subtle">
<h3 class="h6 text-uppercase text-muted mb-3">Feed URL</h3>
</div>
</div>
<div class="col">
<div class="card border border-secondary shadow-sm h-100 rounded-0">
<div class="card-header bg-transparent border-secondary text-muted text-uppercase small fw-semibold">
Feed Configuration
</div>
<div class="card-body">
<section class="mb-3">
<h4 class="h6 text-muted mb-2">Feed URL</h4>
<form action="/change_feed_url" method="post" class="mb-0">
<input type="hidden" name="old_feed_url" value="{{ feed.url }}" />
<div class="input-group input-group-sm feed-page__content">
<div class="input-group input-group-sm">
<input type="url"
class="form-control feed-page__wrap"
name="new_feed_url"
@ -356,22 +347,23 @@
</div>
</form>
</section>
<section class="mt-4 pt-3 border-top border-secondary-subtle">
<h3 class="h6 text-uppercase text-muted mb-3">Webhook</h3>
<hr class="border-secondary" />
<section class="mb-3">
<h4 class="h6 text-muted mb-2">Webhook</h4>
{% if current_webhook_name %}
<p class="text-muted mb-3">
<p class="text-muted small mb-2">
Current webhook:
<strong>{{ current_webhook_name }}</strong>
</p>
{% elif current_webhook_url %}
<p class="text-warning mb-3">This feed references a missing webhook. Choose a webhook below to reattach it.</p>
<p class="text-warning small mb-2">This feed references a missing webhook. Choose a webhook below to reattach it.</p>
{% else %}
<p class="text-warning mb-3">No webhook is attached to this feed yet.</p>
<p class="text-warning small mb-2">No webhook is attached to this feed yet.</p>
{% endif %}
{% if webhooks %}
<form action="/attach_feed_webhook"
method="post"
class="d-flex flex-wrap align-items-center gap-2 mb-0">
class="d-flex flex-wrap align-items-center gap-2 mb-2">
<input type="hidden" name="feed_url" value="{{ feed.url }}" />
<input type="hidden"
name="redirect_to"
@ -394,9 +386,9 @@
<button class="btn btn-outline-light btn-sm" type="submit">Save webhook</button>
</form>
{% else %}
<p class="text-muted mb-0">Add a webhook first to attach this feed.</p>
<p class="text-muted small mb-2">Add a webhook first to attach this feed.</p>
{% endif %}
<div class="mt-3 d-flex flex-wrap align-items-center gap-2">
<div class="d-flex flex-wrap align-items-center gap-2">
<span class="badge {{ 'bg-success' if save_sent_webhooks else 'bg-secondary' }}">
Sent webhook tracking:
{{ 'Enabled' if save_sent_webhooks else 'Disabled' }}
@ -414,34 +406,10 @@
href="/sent_webhooks?feed_url={{ feed.url|encode_url }}">View sent webhooks</a>
</div>
</section>
<section class="mt-4 pt-3 border-top border-secondary-subtle">
<h3 class="h6 text-uppercase text-muted mb-3">Feed Information</h3>
<div class="row g-2 text-muted small">
<div class="col-12 col-md-6">
<div class="p-2">Added: {{ feed.added | relative_time }}</div>
</div>
<div class="col-12 col-md-6">
<div class="p-2">Last Updated: {{ feed.last_updated | relative_time }}</div>
</div>
<div class="col-12 col-md-6">
<div class="p-2">Last Retrieved: {{ feed.last_retrieved | relative_time }}</div>
</div>
<div class="col-12 col-md-6">
<div class="p-2">Next Update: {{ feed.update_after | relative_time }}</div>
</div>
<div class="col-12 col-md-6">
<div class="p-2">
Updates:
<span class="badge {{ 'bg-success' if feed.updates_enabled else 'bg-danger' }}">
{{ 'Enabled' if feed.updates_enabled else 'Disabled' }}
</span>
</div>
</div>
</div>
</section>
<section class="mt-4 pt-3 border-top border-secondary-subtle">
<div class="d-flex flex-wrap align-items-center justify-content-between gap-2 mb-3">
<h3 class="h6 text-uppercase text-muted mb-0">Update Interval</h3>
<hr class="border-secondary" />
<section>
<h4 class="h6 text-muted mb-2">Update Interval</h4>
<div class="d-flex flex-wrap align-items-center gap-2 mb-2">
<span class="badge {% if feed_interval %} bg-info {% else %} bg-secondary {% endif %}">
{% if feed_interval %}
Custom
@ -450,7 +418,7 @@
{% endif %}
</span>
</div>
<p class="text-muted mb-3">
<p class="text-muted small mb-2">
Current:
<strong>
{% if feed_interval %}
@ -487,6 +455,73 @@
</div>
</section>
</div>
</div>
</div>
</div>
<div class="row row-cols-1 row-cols-lg-2 g-3 mt-2">
<div class="col">
<div class="card border border-secondary shadow-sm h-100 rounded-0">
<div class="card-header bg-transparent border-secondary text-muted text-uppercase small fw-semibold">
Customization
</div>
<div class="card-body">
<div class="d-flex flex-wrap gap-2">
<a class="btn btn-sm btn-outline-light"
href="/whitelist?feed_url={{ feed.url|encode_url }}">Whitelist</a>
<a class="btn btn-sm btn-outline-light"
href="/blacklist?feed_url={{ feed.url|encode_url }}">Blacklist</a>
<div class="btn-group btn-group-sm" role="group">
<a class="btn {{ 'btn-primary' if delivery_mode == 'text' else 'btn-outline-light' }}"
href="/custom?feed_url={{ feed.url|encode_url }}">
Customize message
</a>
{% if not "youtube.com/feeds/videos.xml" in feed.url %}
<a class="btn {{ 'btn-primary' if delivery_mode == 'embed' else 'btn-outline-light' }}"
href="/embed?feed_url={{ feed.url|encode_url }}">
Customize embed
</a>
{% endif %}
</div>
</div>
{% if is_steam_feed %}
<div class="form-text small mt-2">Steam feeds can enable thumbnails in embed settings.</div>
{% endif %}
</div>
</div>
</div>
<div class="col">
<div class="card border border-secondary shadow-sm h-100 rounded-0">
<div class="card-header bg-transparent border-secondary text-muted text-uppercase small fw-semibold">
Feed Information
</div>
<div class="card-body">
<div class="row g-2 text-muted small">
<div class="col-12 col-md-6">
<div class="p-2">Added: {{ feed.added | relative_time }}</div>
</div>
<div class="col-12 col-md-6">
<div class="p-2">Last Updated: {{ feed.last_updated | relative_time }}</div>
</div>
<div class="col-12 col-md-6">
<div class="p-2">Last Retrieved: {{ feed.last_retrieved | relative_time }}</div>
</div>
<div class="col-12 col-md-6">
<div class="p-2">Next Update: {{ feed.update_after | relative_time }}</div>
</div>
<div class="col-12 col-md-6">
<div class="p-2">
Updates:
<span class="badge {{ 'bg-success' if feed.updates_enabled else 'bg-danger' }}">
{{ 'Enabled' if feed.updates_enabled else 'Disabled' }}
</span>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</article>
</div>
<div class="col-12">