feather-reader 0.2.2

A minimalist, atproto-native RSS/Atom reader in Rust — your feed subscriptions live in your own PDS.
Documentation
{% extends "base.html" %}

{% block title %}{{ heading }} — FeatherReader{% endblock %}

{% block body %}
<div class="shell" id="shell">

  <header class="topbar">
    <button class="icon-btn" id="rail-toggle" aria-label="Open navigation"
            aria-expanded="false" aria-controls="rail">
      <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"
           stroke-linecap="round" aria-hidden="true">
        <path d="M4 7h16M4 12h16M4 17h16"/>
      </svg>
    </button>
    <h1 class="topbar-title">{{ heading }} <span class="topbar-count">{{ entries.len() }}</span></h1>
    {% if !entries.is_empty() %}
      <button class="icon-btn js-mark-all" type="submit" form="mark-all-form" aria-label="Mark all read">
        <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"
             stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
          <path d="M3 13l4 4L15 9"/><path d="M9 13l4 4 8-8"/>
        </svg>
      </button>
    {% else %}
      <span class="icon-btn" aria-hidden="true"></span>
    {% endif %}
  </header>

  <button class="scrim" id="scrim" tabindex="-1" aria-hidden="true"></button>

  {% include "rail.html" %}

  <main class="content" id="content">
    {% if !flash.is_empty() %}
      <p class="flash" role="status">{{ flash }}</p>
    {% endif %}

    <div class="content-head">
      <h1 class="content-title">{{ heading }}</h1>
      <span class="content-count">{{ entries.len() }} entries</span>
      <span class="content-spacer"></span>
      {% if !entries.is_empty() %}
        <form id="mark-all-form" method="post"
              action="/read-all{% if let Some(f) = feed_scope %}?feed={{ f|urlencode }}{% endif %}">
          <button class="btn-quiet js-mark-all" type="submit">Mark all read</button>
        </form>
      {% endif %}
    </div>

    {% if entries.is_empty() %}
      <div class="empty">
        <svg class="empty-mark" viewBox="0 0 24 24" fill="none" stroke="currentColor"
             stroke-width="1.4" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
          <path d="M20.2 4.6c-2.3-2.3-7.2-1.4-10 1.4C7.4 8.8 4 17 4 20c3 0 11.2-3.4 14-6.2 2.8-2.8 4.5-6.9 2.2-9.2z"/>
          <path d="M16 8 5 19"/>
        </svg>
        <h2 class="empty-title">All caught up</h2>
        <p class="empty-note">Nothing unread. The quiet is the point.</p>
      </div>
    {% else %}
      <ul class="entry-list" id="entry-list">
        {% for e in entries %}
          {% include "entry_row.html" %}
        {% endfor %}
      </ul>
    {% endif %}

    {% include "footer.html" %}
  </main>
</div>

{% include "overlay.html" %}
{% endblock %}