tangled
alpha
login
or
join now
t1c.dev
/
rocksky
forked from
rocksky.app/rocksky
2
fork
atom
A decentralized music tracking and discovery platform built on AT Protocol 🎵
2
fork
atom
overview
issues
pulls
pipelines
Add skeleton loaders for genre pages
tsiry-sandratraina.com
1 month ago
d7b01009
86692b90
+117
3 changed files
expand all
collapse all
unified
split
apps
web
src
pages
genre
albums
Albums.tsx
artists
Artists.tsx
tracks
Tracks.tsx
+34
apps/web/src/pages/genre/albums/Albums.tsx
···
6
import dayjs from "dayjs";
7
import { useEffect, useRef } from "react";
8
import { LabelSmall } from "baseui/typography";
0
9
10
const itemProps: BlockProps = {
11
display: "flex",
···
42
43
return (
44
<>
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
45
{!isLoading && (
46
<>
47
<FlexGrid
···
6
import dayjs from "dayjs";
7
import { useEffect, useRef } from "react";
8
import { LabelSmall } from "baseui/typography";
9
+
import ContentLoader from "react-content-loader";
10
11
const itemProps: BlockProps = {
12
display: "flex",
···
43
44
return (
45
<>
46
+
{isLoading && (
47
+
<FlexGrid
48
+
flexGridColumnCount={[1, 2, 3]}
49
+
flexGridColumnGap="scale800"
50
+
flexGridRowGap="scale1000"
51
+
className="mt-[50px]"
52
+
>
53
+
{/* Generate 12 skeleton items (4 rows x 3 columns) */}
54
+
{[...Array(12)].map((_, index) => (
55
+
<FlexGridItem {...itemProps} key={index}>
56
+
<ContentLoader
57
+
width={230}
58
+
height={330}
59
+
viewBox="0 0 230 330"
60
+
backgroundColor="var(--color-skeleton-background)"
61
+
foregroundColor="var(--color-skeleton-foreground)"
62
+
>
63
+
{/* Square for album art */}
64
+
<rect x="0" y="0" rx="4" ry="4" width="230" height="230" />
65
+
{/* Album title - 2 lines */}
66
+
<rect x="0" y="250" rx="3" ry="3" width="200" height="12" />
67
+
<rect x="0" y="268" rx="3" ry="3" width="150" height="12" />
68
+
{/* Artist name */}
69
+
<rect x="0" y="290" rx="3" ry="3" width="120" height="10" />
70
+
{/* Play count */}
71
+
<rect x="0" y="308" rx="3" ry="3" width="100" height="10" />
72
+
{/* Release date */}
73
+
<rect x="0" y="323" rx="3" ry="3" width="130" height="10" />
74
+
</ContentLoader>
75
+
</FlexGridItem>
76
+
))}
77
+
</FlexGrid>
78
+
)}
79
{!isLoading && (
80
<>
81
<FlexGrid
+29
apps/web/src/pages/genre/artists/Artists.tsx
···
6
import { useEffect, useRef } from "react";
7
import { LabelSmall } from "baseui/typography";
8
import ArtistIcon from "../../../components/Icons/Artist";
0
9
10
const itemProps: BlockProps = {
11
display: "flex",
···
42
43
return (
44
<>
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
45
{!isLoading && (
46
<>
47
<FlexGrid
···
6
import { useEffect, useRef } from "react";
7
import { LabelSmall } from "baseui/typography";
8
import ArtistIcon from "../../../components/Icons/Artist";
9
+
import ContentLoader from "react-content-loader";
10
11
const itemProps: BlockProps = {
12
display: "flex",
···
43
44
return (
45
<>
46
+
{isLoading && (
47
+
<FlexGrid
48
+
flexGridColumnCount={[1, 2, 3]}
49
+
flexGridColumnGap="scale800"
50
+
flexGridRowGap="scale1000"
51
+
className="mt-[50px]"
52
+
>
53
+
{/* Generate 9 skeleton items (3x3 grid) */}
54
+
{[...Array(9)].map((_, index) => (
55
+
<FlexGridItem {...itemProps} key={index}>
56
+
<ContentLoader
57
+
width={200}
58
+
height={250}
59
+
viewBox="0 0 200 250"
60
+
backgroundColor="var(--color-skeleton-background)"
61
+
foregroundColor="var(--color-skeleton-foreground)"
62
+
>
63
+
{/* Circle for artist avatar */}
64
+
<circle cx="100" cy="100" r="100" />
65
+
{/* Artist name */}
66
+
<rect x="50" y="220" rx="3" ry="3" width="100" height="12" />
67
+
{/* Play count */}
68
+
<rect x="60" y="240" rx="3" ry="3" width="80" height="10" />
69
+
</ContentLoader>
70
+
</FlexGridItem>
71
+
))}
72
+
</FlexGrid>
73
+
)}
74
{!isLoading && (
75
<>
76
<FlexGrid
+54
apps/web/src/pages/genre/tracks/Tracks.tsx
···
4
import numeral from "numeral";
5
import { useEffect, useRef } from "react";
6
import { LabelSmall } from "baseui/typography";
0
7
8
type Row = {
9
id: string;
···
47
48
return (
49
<>
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
50
{!isLoading && (
51
<>
52
<TableBuilder
···
4
import numeral from "numeral";
5
import { useEffect, useRef } from "react";
6
import { LabelSmall } from "baseui/typography";
7
+
import ContentLoader from "react-content-loader";
8
9
type Row = {
10
id: string;
···
48
49
return (
50
<>
51
+
{isLoading && (
52
+
<div className="ml-[-150px] mt-[20px]">
53
+
<ContentLoader
54
+
width="100%"
55
+
height={500}
56
+
viewBox="0 0 600 500"
57
+
backgroundColor="var(--color-skeleton-background)"
58
+
foregroundColor="var(--color-skeleton-foreground)"
59
+
>
60
+
{/* Row 1 */}
61
+
<rect x="0" y="10" rx="3" ry="3" width="30" height="15" />
62
+
<rect x="50" y="5" rx="4" ry="4" width="60" height="60" />
63
+
<rect x="130" y="15" rx="3" ry="3" width="200" height="15" />
64
+
<rect x="130" y="40" rx="3" ry="3" width="150" height="12" />
65
+
<rect x="500" y="20" rx="3" ry="3" width="80" height="15" />
66
+
67
+
{/* Row 2 */}
68
+
<rect x="0" y="90" rx="3" ry="3" width="30" height="15" />
69
+
<rect x="50" y="85" rx="4" ry="4" width="60" height="60" />
70
+
<rect x="130" y="95" rx="3" ry="3" width="200" height="15" />
71
+
<rect x="130" y="120" rx="3" ry="3" width="150" height="12" />
72
+
<rect x="500" y="100" rx="3" ry="3" width="80" height="15" />
73
+
74
+
{/* Row 3 */}
75
+
<rect x="0" y="170" rx="3" ry="3" width="30" height="15" />
76
+
<rect x="50" y="165" rx="4" ry="4" width="60" height="60" />
77
+
<rect x="130" y="175" rx="3" ry="3" width="200" height="15" />
78
+
<rect x="130" y="200" rx="3" ry="3" width="150" height="12" />
79
+
<rect x="500" y="180" rx="3" ry="3" width="80" height="15" />
80
+
81
+
{/* Row 4 */}
82
+
<rect x="0" y="250" rx="3" ry="3" width="30" height="15" />
83
+
<rect x="50" y="245" rx="4" ry="4" width="60" height="60" />
84
+
<rect x="130" y="255" rx="3" ry="3" width="200" height="15" />
85
+
<rect x="130" y="280" rx="3" ry="3" width="150" height="12" />
86
+
<rect x="500" y="260" rx="3" ry="3" width="80" height="15" />
87
+
88
+
{/* Row 5 */}
89
+
<rect x="0" y="330" rx="3" ry="3" width="30" height="15" />
90
+
<rect x="50" y="325" rx="4" ry="4" width="60" height="60" />
91
+
<rect x="130" y="335" rx="3" ry="3" width="200" height="15" />
92
+
<rect x="130" y="360" rx="3" ry="3" width="150" height="12" />
93
+
<rect x="500" y="340" rx="3" ry="3" width="80" height="15" />
94
+
95
+
{/* Row 6 */}
96
+
<rect x="0" y="410" rx="3" ry="3" width="30" height="15" />
97
+
<rect x="50" y="405" rx="4" ry="4" width="60" height="60" />
98
+
<rect x="130" y="415" rx="3" ry="3" width="200" height="15" />
99
+
<rect x="130" y="440" rx="3" ry="3" width="150" height="12" />
100
+
<rect x="500" y="420" rx="3" ry="3" width="80" height="15" />
101
+
</ContentLoader>
102
+
</div>
103
+
)}
104
{!isLoading && (
105
<>
106
<TableBuilder