simple-web-app

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README

commit a5c79d2e7b71b6f896cb054cfaf89f8f1c874ee8
parent 2d4964582bb427d63881a6f6cd5b3b09f35264a9
Author: Silas Brack <silasbrack@gmail.com>
Date:   Thu, 11 Jun 2026 12:38:17 +0200

feat: add Datastar loading indicators to interactive elements

Adds data-indicator attributes to vote buttons, search form, and
settings tabs per Datastar Tao guidance. Vote buttons are disabled
during requests, search shows a "Searching..." indicator, and
settings tabs show "Loading..." while fetching tab content.

Also cleans up unused patch_elements_with_selector function.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

Diffstat:
Msrc/sse.rs | 4----
Mstatic/style.css | 7+++++++
Mstatic/style.css.gz | 0
Mtemplates/search.html | 8++++++--
Mtemplates/settings_page.html | 7+++++++
Mtemplates/vote_button.html | 2++
6 files changed, 22 insertions(+), 6 deletions(-)

diff --git a/src/sse.rs b/src/sse.rs @@ -4,10 +4,6 @@ pub fn patch_elements(html: &str) -> Response { patch_elements_with_options(html, None, None) } -pub fn patch_elements_with_selector(html: &str, selector: &str) -> Response { - patch_elements_with_options(html, Some(selector), None) -} - fn patch_elements_with_options( html: &str, selector: Option<&str>, diff --git a/static/style.css b/static/style.css @@ -584,6 +584,13 @@ select.valid { } .site-footer a { color: var(--color-text-secondary); } +/* Loading indicators */ +.loading-indicator { + color: var(--color-text-secondary); + font-size: 0.875rem; + padding: 4px 0; +} + /* Responsive */ @media (max-width: 640px) { :root { --max-width: 100%; } diff --git a/static/style.css.gz b/static/style.css.gz Binary files differ. diff --git a/templates/search.html b/templates/search.html @@ -1,8 +1,12 @@ <div class="search-page"> <h2>Search</h2> - <form class="search-form" data-on:submit__prevent="@post('/search', {contentType: 'form'})" data-on:input__debounce.500ms="@post('/search', {contentType: 'form'})" > + <form class="search-form" + data-on:submit__prevent="@post('/search', {contentType: 'form'})" + data-on:input__debounce.500ms="@post('/search', {contentType: 'form'})" + data-indicator:searching> <input type="search" name="search" placeholder="Search stories..." autofocus /> - <button type="submit">Search</button> + <button type="submit" data-attr:disabled="$searching">Search</button> </form> + <div data-show="$searching" class="loading-indicator">Searching...</div> <div id="search-results"></div> </div> diff --git a/templates/settings_page.html b/templates/settings_page.html @@ -26,6 +26,7 @@ id="general-tab" href="/settings?tab=general" data-on:click__prevent="@get('/settings/tab?tab=general')" + data-indicator:loadingTab > General </a> @@ -35,6 +36,7 @@ id="categories-tab" href="/settings?tab=categories" data-on:click__prevent="@get('/settings/tab?tab=categories')" + data-indicator:loadingTab > Categories </a> @@ -44,6 +46,7 @@ id="sections-tab" href="/settings?tab=sections" data-on:click__prevent="@get('/settings/tab?tab=sections')" + data-indicator:loadingTab > Sections </a> @@ -53,6 +56,7 @@ id="content-filter-tab" href="/settings?tab=content-filter" data-on:click__prevent="@get('/settings/tab?tab=content-filter')" + data-indicator:loadingTab > Content Filter </a> @@ -62,6 +66,7 @@ id="syncing-tab" href="/settings?tab=syncing" data-on:click__prevent="@get('/settings/tab?tab=syncing')" + data-indicator:loadingTab > Syncing </a> @@ -71,6 +76,7 @@ id="experimental-tab" href="/settings?tab=experimental" data-on:click__prevent="@get('/settings/tab?tab=experimental')" + data-indicator:loadingTab > Experimental </a> @@ -79,6 +85,7 @@ </nav> </div> <hr /> + <div data-show="$loadingTab" class="loading-indicator">Loading...</div> {% include "settings_tab.html" %} <footer> <a href="/" role="button" class="secondary">Cancel</a> diff --git a/templates/vote_button.html b/templates/vote_button.html @@ -2,5 +2,7 @@ <button class="vote-btn{% if voted %} voted{% endif %}" data-on:click="@post('/vote/{{ target_type }}/{{ target_id }}')" + data-indicator:voting + data-attr:disabled="$voting" >&#9650;</button> </span>