skeleton on initial load + spinner for infinite scroll

This commit is contained in:
BFlat committed 2023-12-27 02:46:27 +07:00
1 parent b36b396365
commit a4e68fe788
6 files changed
+222 -190

No files matched your search

@@ -8,6 +8,7 @@ import { faChevronRight } from "@fortawesome/pro-solid-svg-icons";
import { MediaFile } from "@storyteller/components/src/api/media_files/GetMedia";
import { useLazyLists } from "hooks";
import { ListFeaturedMediaFiles } from "@storyteller/components/src/api/media_files/ListFeaturedMediaFiles";
import SkeletonCard from "components/common/Card/SkeletonCard";
export default function FeaturedTab() {
const gridContainerRef = useRef<HTMLDivElement | null>(null);
@@ -42,10 +43,10 @@ export default function FeaturedTab() {
</div>
{isLoading ? (
<div className="mt-4 d-flex justify-content-center">
<div className="spinner-border text-light" role="status">
<span className="visually-hidden">Loading...</span>
</div>
<div className="row gx-3 gy-3">
{Array.from({ length: 12 }).map((_, index) => (
<SkeletonCard key={index} />
))}
</div>
) : (
<>
@@ -1,4 +1,4 @@
import React, { useRef, useState } from "react";
import React, { useEffect, useRef, useState } from "react";
import MasonryGrid from "components/common/MasonryGrid/MasonryGrid";
import AudioCard from "components/common/Card/AudioCard";
import ImageCard from "components/common/Card/ImageCard";
@@ -9,7 +9,7 @@ import {
faFilter,
} from "@fortawesome/pro-solid-svg-icons";
import AudioPlayerProvider from "components/common/AudioPlayer/AudioPlayerContext";
import SkeletonCard from "components/common/Card/SkeletonCard";
import { ListMediaFiles } from "@storyteller/components/src/api/media_files/ListMediaFiles";
import { MediaFile } from "@storyteller/components/src/api/media_files/GetMedia";
import { useLazyLists } from "hooks";
@@ -18,6 +18,7 @@ import InfiniteScroll from "react-infinite-scroll-component";
export default function MediaTab() {
const gridContainerRef = useRef<HTMLDivElement | null>(null);
const [showMasonryGrid, setShowMasonryGrid] = useState(true);
const [isLoading, setIsLoading] = useState(true);
const [list, listSet] = useState<MediaFile[]>([]);
const media = useLazyLists({
@@ -55,6 +56,12 @@ export default function MediaTab() {
// { value: "mostliked", label: "Most Liked" },
];
useEffect(() => {
if (media.status === 3) {
setIsLoading(false);
}
}, [media.status]);
return (
<>
<div className="d-flex flex-wrap gap-3 mb-3">
@@ -80,83 +87,91 @@ export default function MediaTab() {
</div>
</div>
<AudioPlayerProvider>
<InfiniteScroll
dataLength={media.list.length}
next={media.getMore}
hasMore={!media.list.length || !!media.next}
loader={
<div className="mt-4 d-flex justify-content-center">
<div className="spinner-border text-light" role="status">
<span className="visually-hidden">Loading...</span>
</div>
</div>
}
endMessage={
<p className="text-center mt-4 opacity-75">No more results.</p>
}
className="overflow-hidden"
>
{showMasonryGrid && (
<>
{media.list.length === 0 && media.status === 3 ? (
<div className="text-center mt-4 opacity-75">
No media created yet.
{isLoading ? (
<div className="row gx-3 gy-3">
{Array.from({ length: 12 }).map((_, index) => (
<SkeletonCard key={index} />
))}
</div>
) : (
<InfiniteScroll
dataLength={media.list.length}
next={media.getMore}
hasMore={!media.list.length || !!media.next}
loader={
<div className="mt-4 d-flex justify-content-center">
<div className="spinner-border text-light" role="status">
<span className="visually-hidden">Loading...</span>
</div>
) : (
<MasonryGrid
gridRef={gridContainerRef}
onLayoutComplete={() => console.log("Layout complete!")}
>
{media.list.map((data: any, index: number) => {
let card;
switch (data.media_type) {
case "audio":
card = (
<AudioCard
key={index}
data={data}
type="media"
showCreator={true}
/>
);
break;
case "image":
card = (
<ImageCard
key={index}
data={data}
type="media"
showCreator={true}
/>
);
break;
case "video":
card = (
<VideoCard
key={index}
data={data}
type="media"
showCreator={true}
/>
);
break;
default:
card = <div>Unsupported media type</div>;
}
return (
<div
key={index}
className="col-12 col-sm-6 col-xl-4 grid-item"
>
{card}
</div>
);
})}
</MasonryGrid>
)}
</>
)}
</InfiniteScroll>
</div>
}
endMessage={
<p className="text-center mt-4 opacity-75">No more results.</p>
}
className="overflow-hidden"
>
{showMasonryGrid && (
<>
{media.list.length === 0 && media.status === 3 ? (
<div className="text-center mt-4 opacity-75">
No media created yet.
</div>
) : (
<MasonryGrid
gridRef={gridContainerRef}
onLayoutComplete={() => console.log("Layout complete!")}
>
{media.list.map((data: any, index: number) => {
let card;
switch (data.media_type) {
case "audio":
card = (
<AudioCard
key={index}
data={data}
type="media"
showCreator={true}
/>
);
break;
case "image":
card = (
<ImageCard
key={index}
data={data}
type="media"
showCreator={true}
/>
);
break;
case "video":
card = (
<VideoCard
key={index}
data={data}
type="media"
showCreator={true}
/>
);
break;
default:
card = <div>Unsupported media type</div>;
}
return (
<div
key={index}
className="col-12 col-sm-6 col-xl-4 grid-item"
>
{card}
</div>
);
})}
</MasonryGrid>
)}
</>
)}
</InfiniteScroll>
)}
</AudioPlayerProvider>
</>
);
@@ -1,4 +1,4 @@
import React, { useRef, useState } from "react";
import React, { useEffect, useRef, useState } from "react";
import MasonryGrid from "components/common/MasonryGrid/MasonryGrid";
import AudioCard from "components/common/Card/AudioCard";
import ImageCard from "components/common/Card/ImageCard";
@@ -9,7 +9,7 @@ import {
faFilter,
} from "@fortawesome/pro-solid-svg-icons";
import AudioPlayerProvider from "components/common/AudioPlayer/AudioPlayerContext";
import SkeletonCard from "components/common/Card/SkeletonCard";
import { ListWeights } from "@storyteller/components/src/api/weights/ListWeights";
import { Weight } from "@storyteller/components/src/api/weights/GetWeight";
import InfiniteScroll from "react-infinite-scroll-component";
@@ -19,6 +19,7 @@ import { useLazyLists } from "hooks";
export default function WeightsTab() {
const gridContainerRef = useRef<HTMLDivElement | null>(null);
const [showMasonryGrid, setShowMasonryGrid] = useState(true);
const [isLoading, setIsLoading] = useState(true);
const [list, listSet] = useState<Weight[]>([]);
const weights = useLazyLists({
@@ -74,6 +75,12 @@ export default function WeightsTab() {
// { value: "SDXL", label: "SD XL" },
// ];
useEffect(() => {
if (weights.status === 3) {
setIsLoading(false);
}
}, [weights.status]);
return (
<>
<div className="d-flex flex-wrap gap-3 mb-3">
@@ -120,99 +127,107 @@ export default function WeightsTab() {
</div>
</div>
<AudioPlayerProvider>
<InfiniteScroll
dataLength={weights.list.length}
next={weights.getMore}
hasMore={!weights.list.length || !!weights.next}
loader={
<div className="mt-4 d-flex justify-content-center">
<div className="spinner-border text-light" role="status">
<span className="visually-hidden">Loading...</span>
</div>
</div>
}
endMessage={
<p className="text-center mt-4 opacity-75">No more results.</p>
}
className="overflow-hidden"
>
{showMasonryGrid && (
<>
{weights.list.length === 0 && weights.status === 3 ? (
<div className="text-center mt-4 opacity-75">
No weight created yet.
{isLoading ? (
<div className="row gx-3 gy-3">
{Array.from({ length: 12 }).map((_, index) => (
<SkeletonCard key={index} />
))}
</div>
) : (
<InfiniteScroll
dataLength={weights.list.length}
next={weights.getMore}
hasMore={!weights.list.length || !!weights.next}
loader={
<div className="mt-4 d-flex justify-content-center">
<div className="spinner-border text-light" role="status">
<span className="visually-hidden">Loading...</span>
</div>
) : (
<MasonryGrid
gridRef={gridContainerRef}
onLayoutComplete={() => console.log("Layout complete!")}
>
{weights.list.map((data: any, index: number) => {
let card;
switch (data.weights_category) {
case WeightCategory.TTS:
card = (
<AudioCard
key={index}
data={data}
type="weights"
showCreator={true}
showCover={true}
/>
);
break;
case WeightCategory.VC:
card = (
<AudioCard
key={index}
data={data}
type="weights"
showCreator={true}
showCover={true}
/>
);
break;
case WeightCategory.ZS:
card = (
<AudioCard
key={index}
data={data}
type="weights"
showCreator={true}
showCover={true}
/>
);
break;
case WeightCategory.SD:
card = (
<ImageCard
key={index}
data={data}
type="weights"
showCreator={true}
/>
);
break;
case WeightCategory.VOCODER:
card = <></>;
break;
default:
card = <div>Unsupported weight type</div>;
}
return (
<div
key={index}
className="col-12 col-sm-6 col-xl-4 grid-item"
>
{card}
</div>
);
})}
</MasonryGrid>
)}
</>
)}
</InfiniteScroll>
</div>
}
endMessage={
<p className="text-center mt-4 opacity-75">No more results.</p>
}
className="overflow-hidden"
>
{showMasonryGrid && (
<>
{weights.list.length === 0 && weights.status === 3 ? (
<div className="text-center mt-4 opacity-75">
No weight created yet.
</div>
) : (
<MasonryGrid
gridRef={gridContainerRef}
onLayoutComplete={() => console.log("Layout complete!")}
>
{weights.list.map((data: any, index: number) => {
let card;
switch (data.weights_category) {
case WeightCategory.TTS:
card = (
<AudioCard
key={index}
data={data}
type="weights"
showCreator={true}
showCover={true}
/>
);
break;
case WeightCategory.VC:
card = (
<AudioCard
key={index}
data={data}
type="weights"
showCreator={true}
showCover={true}
/>
);
break;
case WeightCategory.ZS:
card = (
<AudioCard
key={index}
data={data}
type="weights"
showCreator={true}
showCover={true}
/>
);
break;
case WeightCategory.SD:
card = (
<ImageCard
key={index}
data={data}
type="weights"
showCreator={true}
/>
);
break;
case WeightCategory.VOCODER:
card = <></>;
break;
default:
card = <div>Unsupported weight type</div>;
}
return (
<div
key={index}
className="col-12 col-sm-6 col-xl-4 grid-item"
>
{card}
</div>
);
})}
</MasonryGrid>
)}
</>
)}
</InfiniteScroll>
)}
</AudioPlayerProvider>
</>
);
@@ -3,7 +3,7 @@ import MasonryGrid from "components/common/MasonryGrid/MasonryGrid";
import AudioCard from "components/common/Card/AudioCard";
import ImageCard from "components/common/Card/ImageCard";
import VideoCard from "components/common/Card/VideoCard";
import SkeletonCard from "components/common/Card/SkeletonCard";
import Select from "components/common/Select";
import {
faArrowDownWideShort,
@@ -142,10 +142,10 @@ export default function BookmarksTab({ username }: { username: string }) {
<Pagination {...paginationProps} />
</div>
{isLoading ? (
<div className="mt-4 d-flex justify-content-center">
<div className="spinner-border text-light" role="status">
<span className="visually-hidden">Loading...</span>
</div>
<div className="row gx-3 gy-3">
{Array.from({ length: 12 }).map((_, index) => (
<SkeletonCard key={index} />
))}
</div>
) : (
<>
@@ -9,7 +9,7 @@ import {
faFilter,
} from "@fortawesome/pro-solid-svg-icons";
import AudioPlayerProvider from "components/common/AudioPlayer/AudioPlayerContext";
import SkeletonCard from "components/common/Card/SkeletonCard";
import Pagination from "components/common/Pagination";
import { GetMediaByUser } from "@storyteller/components/src/api/media_files/GetMediaByUser";
@@ -105,10 +105,10 @@ export default function MediaTab({ username }: { username: string }) {
</div>
<AudioPlayerProvider>
{isLoading ? (
<div className="mt-4 d-flex justify-content-center">
<div className="spinner-border text-light" role="status">
<span className="visually-hidden">Loading...</span>
</div>
<div className="row gx-3 gy-3">
{Array.from({ length: 12 }).map((_, index) => (
<SkeletonCard key={index} />
))}
</div>
) : (
<>
@@ -11,6 +11,7 @@ import { useListContent } from "hooks";
import { GetWeightsByUser } from "@storyteller/components/src/api/weights/GetWeightsByUser";
import { TempSelect } from "components/common";
import { WeightCategory } from "@storyteller/components/src/api/_common/enums/WeightCategory";
import SkeletonCard from "components/common/Card/SkeletonCard";
// interface IWeighttModelData {
// token: string;
@@ -162,10 +163,10 @@ export default function WeightsTab({ username }: { username: string }) {
<Pagination {...paginationProps} />
</div>
{isLoading ? (
<div className="mt-4 d-flex justify-content-center">
<div className="spinner-border text-light" role="status">
<span className="visually-hidden">Loading...</span>
</div>
<div className="row gx-3 gy-3">
{Array.from({ length: 12 }).map((_, index) => (
<SkeletonCard key={index} />
))}
</div>
) : (
<>