mirror of
https://github.com/svemagie/indiekit-endpoint-activitypub.git
synced 2026-04-02 15:44:58 +02:00
feat: skeleton loaders replace loading text (Release 6)
Animated card-shaped placeholders with shimmer effect shown during content loading instead of plain "Loading..." text. Applied to reader, tag timeline, and explore tabs (both first-load and load-more states). Confab-Link: http://localhost:8080/sessions/e9d666ac-3c90-4298-9e92-9ac9d142bc06
This commit is contained in:
@@ -256,10 +256,14 @@
|
||||
x-data="apInfiniteScroll()"
|
||||
x-init="init()">
|
||||
<div class="ap-load-more__sentinel" x-ref="sentinel"></div>
|
||||
<button class="ap-load-more__btn" @click="loadMore()" :disabled="loading" x-show="!done">
|
||||
<span x-show="!loading">{{ __("activitypub.reader.pagination.loadMore") }}</span>
|
||||
<span x-show="loading">{{ __("activitypub.reader.pagination.loading") }}</span>
|
||||
<button class="ap-load-more__btn" @click="loadMore()" :disabled="loading" x-show="!done && !loading">
|
||||
{{ __("activitypub.reader.pagination.loadMore") }}
|
||||
</button>
|
||||
<div class="ap-skeleton-group" x-show="loading" x-cloak>
|
||||
{% include "partials/ap-skeleton-card.njk" %}
|
||||
{% include "partials/ap-skeleton-card.njk" %}
|
||||
{% include "partials/ap-skeleton-card.njk" %}
|
||||
</div>
|
||||
<p class="ap-load-more__done" x-show="done" x-cloak>{{ __("activitypub.reader.pagination.noMore") }}</p>
|
||||
</div>
|
||||
{% endif %}
|
||||
@@ -283,10 +287,12 @@
|
||||
<template x-if="tab.type === 'instance'">
|
||||
<div class="ap-explore-instance-panel">
|
||||
|
||||
{# Loading spinner — first load, no content yet #}
|
||||
<div class="ap-explore-tab-loading"
|
||||
{# Skeleton loaders — first load, no content yet #}
|
||||
<div class="ap-skeleton-group"
|
||||
x-show="tabState[tab._id] && tabState[tab._id].loading && !tabState[tab._id].html">
|
||||
<span class="ap-explore-tab-loading__text">{{ __("activitypub.reader.pagination.loading") }}</span>
|
||||
{% include "partials/ap-skeleton-card.njk" %}
|
||||
{% include "partials/ap-skeleton-card.njk" %}
|
||||
{% include "partials/ap-skeleton-card.njk" %}
|
||||
</div>
|
||||
|
||||
{# Error state with retry #}
|
||||
@@ -304,7 +310,7 @@
|
||||
x-html="tabState[tab._id] ? tabState[tab._id].html : ''">
|
||||
</div>
|
||||
|
||||
{# Load more button + loading spinner for subsequent pages #}
|
||||
{# Load more button + skeleton loaders for subsequent pages #}
|
||||
<div class="ap-load-more"
|
||||
x-show="tabState[tab._id] && tabState[tab._id].html && !tabState[tab._id].done">
|
||||
<button class="ap-load-more__btn"
|
||||
@@ -313,10 +319,11 @@
|
||||
:disabled="tabState[tab._id]?.loading">
|
||||
{{ __("activitypub.reader.pagination.loadMore") }}
|
||||
</button>
|
||||
<span class="ap-explore-tab-loading__text"
|
||||
<div class="ap-skeleton-group"
|
||||
x-show="tabState[tab._id]?.loading">
|
||||
{{ __("activitypub.reader.pagination.loading") }}
|
||||
</span>
|
||||
{% include "partials/ap-skeleton-card.njk" %}
|
||||
{% include "partials/ap-skeleton-card.njk" %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{# Empty state — loaded successfully but no posts #}
|
||||
@@ -347,10 +354,12 @@
|
||||
x-text="hashtagSourcesLine(tab)"
|
||||
x-cloak></p>
|
||||
|
||||
{# Loading spinner — first load, no content yet #}
|
||||
<div class="ap-explore-tab-loading"
|
||||
{# Skeleton loaders — first load, no content yet #}
|
||||
<div class="ap-skeleton-group"
|
||||
x-show="tabState[tab._id] && tabState[tab._id].loading && !tabState[tab._id].html">
|
||||
<span class="ap-explore-tab-loading__text">{{ __("activitypub.reader.pagination.loading") }}</span>
|
||||
{% include "partials/ap-skeleton-card.njk" %}
|
||||
{% include "partials/ap-skeleton-card.njk" %}
|
||||
{% include "partials/ap-skeleton-card.njk" %}
|
||||
</div>
|
||||
|
||||
{# Error state with retry #}
|
||||
@@ -368,7 +377,7 @@
|
||||
x-html="tabState[tab._id] ? tabState[tab._id].html : ''">
|
||||
</div>
|
||||
|
||||
{# Load more button + loading spinner for subsequent pages #}
|
||||
{# Load more button + skeleton loaders for subsequent pages #}
|
||||
<div class="ap-load-more"
|
||||
x-show="tabState[tab._id] && tabState[tab._id].html && !tabState[tab._id].done">
|
||||
<button class="ap-load-more__btn"
|
||||
@@ -377,10 +386,11 @@
|
||||
:disabled="tabState[tab._id]?.loading">
|
||||
{{ __("activitypub.reader.pagination.loadMore") }}
|
||||
</button>
|
||||
<span class="ap-explore-tab-loading__text"
|
||||
<div class="ap-skeleton-group"
|
||||
x-show="tabState[tab._id]?.loading">
|
||||
{{ __("activitypub.reader.pagination.loading") }}
|
||||
</span>
|
||||
{% include "partials/ap-skeleton-card.njk" %}
|
||||
{% include "partials/ap-skeleton-card.njk" %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{# Empty state — no instance tabs pinned yet #}
|
||||
|
||||
@@ -150,10 +150,14 @@
|
||||
x-data="apInfiniteScroll()"
|
||||
x-init="init()">
|
||||
<div class="ap-load-more__sentinel" x-ref="sentinel"></div>
|
||||
<button class="ap-load-more__btn" @click="loadMore()" :disabled="loading" x-show="!done">
|
||||
<span x-show="!loading">{{ __("activitypub.reader.pagination.loadMore") }}</span>
|
||||
<span x-show="loading">{{ __("activitypub.reader.pagination.loading") }}</span>
|
||||
<button class="ap-load-more__btn" @click="loadMore()" :disabled="loading" x-show="!done && !loading">
|
||||
{{ __("activitypub.reader.pagination.loadMore") }}
|
||||
</button>
|
||||
<div class="ap-skeleton-group" x-show="loading" x-cloak>
|
||||
{% include "partials/ap-skeleton-card.njk" %}
|
||||
{% include "partials/ap-skeleton-card.njk" %}
|
||||
{% include "partials/ap-skeleton-card.njk" %}
|
||||
</div>
|
||||
<p class="ap-load-more__done" x-show="done" x-cloak>{{ __("activitypub.reader.pagination.noMore") }}</p>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
@@ -75,10 +75,14 @@
|
||||
x-data="apInfiniteScroll()"
|
||||
x-init="init()">
|
||||
<div class="ap-load-more__sentinel" x-ref="sentinel"></div>
|
||||
<button class="ap-load-more__btn" @click="loadMore()" :disabled="loading" x-show="!done">
|
||||
<span x-show="!loading">{{ __("activitypub.reader.pagination.loadMore") }}</span>
|
||||
<span x-show="loading">{{ __("activitypub.reader.pagination.loading") }}</span>
|
||||
<button class="ap-load-more__btn" @click="loadMore()" :disabled="loading" x-show="!done && !loading">
|
||||
{{ __("activitypub.reader.pagination.loadMore") }}
|
||||
</button>
|
||||
<div class="ap-skeleton-group" x-show="loading" x-cloak>
|
||||
{% include "partials/ap-skeleton-card.njk" %}
|
||||
{% include "partials/ap-skeleton-card.njk" %}
|
||||
{% include "partials/ap-skeleton-card.njk" %}
|
||||
</div>
|
||||
<p class="ap-load-more__done" x-show="done">{{ __("activitypub.reader.pagination.noMore") }}</p>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
15
views/partials/ap-skeleton-card.njk
Normal file
15
views/partials/ap-skeleton-card.njk
Normal file
@@ -0,0 +1,15 @@
|
||||
{# Skeleton loading card — animated placeholder while content loads #}
|
||||
<div class="ap-card ap-card--skeleton" aria-hidden="true">
|
||||
<header class="ap-card__author">
|
||||
<div class="ap-skeleton ap-skeleton--avatar"></div>
|
||||
<div class="ap-skeleton-lines">
|
||||
<div class="ap-skeleton ap-skeleton--name"></div>
|
||||
<div class="ap-skeleton ap-skeleton--handle"></div>
|
||||
</div>
|
||||
</header>
|
||||
<div class="ap-skeleton-body">
|
||||
<div class="ap-skeleton ap-skeleton--line"></div>
|
||||
<div class="ap-skeleton ap-skeleton--line"></div>
|
||||
<div class="ap-skeleton ap-skeleton--line ap-skeleton--short"></div>
|
||||
</div>
|
||||
</div>
|
||||
Reference in New Issue
Block a user