diff --git a/src/components/AudiobookExportModal.tsx b/src/components/AudiobookExportModal.tsx index 70095db..f15828f 100644 --- a/src/components/AudiobookExportModal.tsx +++ b/src/components/AudiobookExportModal.tsx @@ -7,7 +7,6 @@ import { ProgressPopup } from '@/components/ProgressPopup'; import { ProgressCard } from '@/components/ProgressCard'; import { DownloadIcon, CheckCircleIcon, XCircleIcon, ClockIcon, ChevronUpDownIcon, RefreshIcon, DotsVerticalIcon } from '@/components/icons/Icons'; import { ConfirmDialog } from '@/components/ConfirmDialog'; -import { LoadingSpinner } from '@/components/Spinner'; import { useConfig } from '@/contexts/ConfigContext'; import { useTTS } from '@/contexts/TTSContext'; import { VoicesControlBase } from '@/components/player/VoicesControlBase'; @@ -472,9 +471,7 @@ export function AudiobookExportModal({ subtitle="Only leaving the document cancels generation." > {isLoadingExisting ? ( -
- -
+ ) : ( <>
@@ -937,3 +934,50 @@ export function AudiobookExportModal({ ); } + +function AudiobookSettingsSkeleton() { + return ( +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ +
+
+
+
+
+ {Array.from({ length: 4 }).map((_, index) => ( +
+ ))} +
+
+
+ ); +} diff --git a/src/components/admin/AdminFeaturesPanel.tsx b/src/components/admin/AdminFeaturesPanel.tsx index 14c6e69..b1f5975 100644 --- a/src/components/admin/AdminFeaturesPanel.tsx +++ b/src/components/admin/AdminFeaturesPanel.tsx @@ -172,9 +172,7 @@ export function AdminFeaturesPanel() { if (!data) { return ( -
-

Fetching current values…

-
+ ); } @@ -340,6 +338,46 @@ export function AdminFeaturesPanel() { ); } +function AdminFeaturesSkeleton() { + return ( +
+
} + > +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ +
} + > +
+
+
+
+
+
+
+ ); +} + function SourceBadge({ source, dirty, diff --git a/src/components/admin/AdminProvidersPanel.tsx b/src/components/admin/AdminProvidersPanel.tsx index 4384d99..6a0663d 100644 --- a/src/components/admin/AdminProvidersPanel.tsx +++ b/src/components/admin/AdminProvidersPanel.tsx @@ -502,7 +502,7 @@ export function AdminProvidersPanel() {
{isLoading ? ( -

Loading…

+ ) : providers.length === 0 ? (

No shared providers configured yet.

) : ( @@ -547,3 +547,28 @@ export function AdminProvidersPanel() { ); } + +function ProvidersListSkeleton() { + const rows = Array.from({ length: 4 }); + return ( +
+ {rows.map((_, index) => ( +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ))} +
+ ); +} diff --git a/src/components/documents/DocumentSelectionModal.tsx b/src/components/documents/DocumentSelectionModal.tsx index 4084a1e..666b5a1 100644 --- a/src/components/documents/DocumentSelectionModal.tsx +++ b/src/components/documents/DocumentSelectionModal.tsx @@ -164,7 +164,7 @@ export function DocumentSelectionModal({
{isLoading ? ( -
Loading documents...
+ ) : errorMessage ? (
{errorMessage}
) : files.length === 0 ? ( @@ -229,3 +229,18 @@ export function DocumentSelectionModal({ ); } + +function DocumentSelectionSkeleton() { + const rows = Array.from({ length: 9 }); + return ( +
+ {rows.map((_, index) => ( +
+
+
+
+
+ ))} +
+ ); +} diff --git a/src/components/reader/SegmentsSidebar.tsx b/src/components/reader/SegmentsSidebar.tsx index 5219932..e7a84f1 100644 --- a/src/components/reader/SegmentsSidebar.tsx +++ b/src/components/reader/SegmentsSidebar.tsx @@ -631,7 +631,7 @@ export function SegmentsSidebar({ isOpen, setIsOpen, documentId, epubBookRef }: ) : null} ) : isManifestLoading ? ( - Loading… +
) : hasManifestError ? ( error ) : ( @@ -645,7 +645,7 @@ export function SegmentsSidebar({ isOpen, setIsOpen, documentId, epubBookRef }:
{manifestErrorMessage}
)} {isManifestLoading && ( -
Loading segments…
+ )} {hasLoadedManifest && rowsToRender.length === 0 && (
@@ -787,13 +787,52 @@ export function SegmentsSidebar({ isOpen, setIsOpen, documentId, epubBookRef }: )} {hasLoadedManifest && isLoadingMoreManifest && ( -
Loading more segments…
+ )}
); } +function SegmentsListSkeleton() { + return ( +
+
+
+ {Array.from({ length: 8 }).map((_, index) => ( +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ))} +
+
+ ); +} + +function SegmentsListSkeletonRows() { + return ( +
+
+ {Array.from({ length: 3 }).map((_, index) => ( +
+ ))} +
+
+ ); +} + function SegmentMetadataPopover({ row }: { row: TTSSegmentRow }) { return (