Add categories, with failed message as fallback
This commit is contained in:
parent
90e23e64ab
commit
97adc6cf14
6 changed files with 278 additions and 2 deletions
BIN
bun.lockb
BIN
bun.lockb
Binary file not shown.
|
@ -11,7 +11,7 @@
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@astrojs/node": "^8.3.3",
|
"@astrojs/node": "^8.3.3",
|
||||||
"astro": "^4.14.2"
|
"astro": "^4.14.3"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"sass-embedded": "^1.77.8"
|
"sass-embedded": "^1.77.8"
|
||||||
|
|
81
src/components/Category.astro
Normal file
81
src/components/Category.astro
Normal file
|
@ -0,0 +1,81 @@
|
||||||
|
---
|
||||||
|
// Properties
|
||||||
|
const {
|
||||||
|
Name,
|
||||||
|
CategoryType
|
||||||
|
} = Astro.props
|
||||||
|
|
||||||
|
// Components
|
||||||
|
import Video from '@components/Video.astro'
|
||||||
|
|
||||||
|
// Fetching
|
||||||
|
const Videos = await fetch('https://yt.sudovanilla.org/api/v1/trending?type=' + CategoryType)
|
||||||
|
.then((response) => response.json())
|
||||||
|
.catch((error) => {})
|
||||||
|
|
||||||
|
if (Videos === undefined) {var Failed = true}
|
||||||
|
else {var Failed = false}
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
<div class="category">
|
||||||
|
<div class="category-start">
|
||||||
|
<h2>{Name}</h2>
|
||||||
|
<a href="#">See More</a>
|
||||||
|
</div>
|
||||||
|
<div class="category-end">
|
||||||
|
{Failed ?
|
||||||
|
<p>Failed to load.</p>
|
||||||
|
:
|
||||||
|
Videos.map((data) =>
|
||||||
|
<Video
|
||||||
|
ID={data.videoId}
|
||||||
|
Title={data.title}
|
||||||
|
Creator={data.author}
|
||||||
|
Views={data.viewCount}
|
||||||
|
UploadDate={data.published}
|
||||||
|
Length={data.lengthSeconds}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<style lang="scss" is:global>
|
||||||
|
.category {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 24px;
|
||||||
|
.category-start {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
.category-end {
|
||||||
|
display: flex;
|
||||||
|
box-sizing: border-box;
|
||||||
|
white-space: nowrap;
|
||||||
|
position: relative;
|
||||||
|
overflow-x: scroll;
|
||||||
|
overflow-y: hidden;
|
||||||
|
align-items: center;
|
||||||
|
gap: 24px;
|
||||||
|
padding-bottom: 24px;
|
||||||
|
.video-item {
|
||||||
|
min-width: 300px !important;
|
||||||
|
p#vi-title {
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.category-end::-webkit-scrollbar {
|
||||||
|
background: transparent;
|
||||||
|
height: 6px;
|
||||||
|
}
|
||||||
|
.category-end::-webkit-scrollbar-thumb {
|
||||||
|
background: white;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
174
src/components/CategorySkeleton.astro
Normal file
174
src/components/CategorySkeleton.astro
Normal file
|
@ -0,0 +1,174 @@
|
||||||
|
<div class="category">
|
||||||
|
<div class="category-start">
|
||||||
|
<div class="loading-skel"></div>
|
||||||
|
<div class="loading-skel"></div>
|
||||||
|
</div>
|
||||||
|
<div class="category-end">
|
||||||
|
<div class="loading-skel-video"></div>
|
||||||
|
<div class="loading-skel-video"></div>
|
||||||
|
<div class="loading-skel-video"></div>
|
||||||
|
<div class="loading-skel-video"></div>
|
||||||
|
<div class="loading-skel-video"></div>
|
||||||
|
<div class="loading-skel-video"></div>
|
||||||
|
<div class="loading-skel-video"></div>
|
||||||
|
<div class="loading-skel-video"></div>
|
||||||
|
<div class="loading-skel-video"></div>
|
||||||
|
<div class="loading-skel-video"></div>
|
||||||
|
<div class="loading-skel-video"></div>
|
||||||
|
<div class="loading-skel-video"></div>
|
||||||
|
<div class="loading-skel-video"></div>
|
||||||
|
<div class="loading-skel-video"></div>
|
||||||
|
<div class="loading-skel-video"></div>
|
||||||
|
<div class="loading-skel-video"></div>
|
||||||
|
<div class="loading-skel-video"></div>
|
||||||
|
<div class="loading-skel-video"></div>
|
||||||
|
<div class="loading-skel-video"></div>
|
||||||
|
<div class="loading-skel-video"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
@keyframes wave-lines {
|
||||||
|
0% {
|
||||||
|
background-position: -468px 0;
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
background-position: 468px 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@keyframes wave-squares {
|
||||||
|
0% {
|
||||||
|
background-position: -468px 0;
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
background-position: 468px 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.loading-skel {
|
||||||
|
height: 32px;
|
||||||
|
background: linear-gradient(to right, rgba(130, 130, 130, 0.2) 8%, rgba(130, 130, 130, 0.3) 18%, rgba(130, 130, 130, 0.2) 33%);
|
||||||
|
background-size: 800px 100px;
|
||||||
|
animation: wave-lines 1s infinite ease-out;
|
||||||
|
border-radius: 12px;
|
||||||
|
padding: 12px;
|
||||||
|
max-width: 100px;
|
||||||
|
min-width: 100px;
|
||||||
|
width: 100%;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
.loading-skel-avatar {
|
||||||
|
background: linear-gradient(to right, rgba(130, 130, 130, 0.2) 8%, rgba(130, 130, 130, 0.3) 18%, rgba(130, 130, 130, 0.2) 33%);
|
||||||
|
background-size: 800px 100px;
|
||||||
|
animation: wave-lines 1s infinite ease-out;
|
||||||
|
border-radius: 3rem;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
display: flex;
|
||||||
|
aspect-ratio: 1;
|
||||||
|
width: 137.7px;
|
||||||
|
height: 65px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.loading-skel-video {
|
||||||
|
height: 232px;
|
||||||
|
margin-bottom: 6px;
|
||||||
|
background: linear-gradient(to right, rgba(130, 130, 130, 0.2) 8%, rgba(130, 130, 130, 0.3) 18%, rgba(130, 130, 130, 0.2) 33%);
|
||||||
|
background-size: 800px 100px;
|
||||||
|
animation: wave-lines 2s infinite ease-out;
|
||||||
|
border-radius: 12px;
|
||||||
|
min-width: 400px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.channel {
|
||||||
|
.channel-header {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
padding: 0px 24px;
|
||||||
|
.channel-header-start {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 24px;
|
||||||
|
img {
|
||||||
|
width: 64px;
|
||||||
|
height: 64px;
|
||||||
|
border-radius: 3rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.channel-header-end {
|
||||||
|
button {
|
||||||
|
color: black;
|
||||||
|
background: white;
|
||||||
|
border: none;
|
||||||
|
border-radius: 3rem;
|
||||||
|
padding: 8px 16px;
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.tabs {
|
||||||
|
display: flex;
|
||||||
|
gap: 12px;
|
||||||
|
margin: 16px 0px;
|
||||||
|
padding: 0px 24px;
|
||||||
|
a {
|
||||||
|
color: white;
|
||||||
|
text-decoration: none;
|
||||||
|
background: #373737;
|
||||||
|
padding: 12px 24px;
|
||||||
|
border-radius: 6px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.video-grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
|
||||||
|
grid-gap: 25px;
|
||||||
|
max-width: 100%;
|
||||||
|
margin: auto;
|
||||||
|
padding: 0px 24px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<style lang="scss" is:global>
|
||||||
|
.category {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 24px;
|
||||||
|
.category-start {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
.category-end {
|
||||||
|
display: flex;
|
||||||
|
box-sizing: border-box;
|
||||||
|
white-space: nowrap;
|
||||||
|
position: relative;
|
||||||
|
overflow-x: scroll;
|
||||||
|
overflow-y: hidden;
|
||||||
|
align-items: center;
|
||||||
|
gap: 24px;
|
||||||
|
padding-bottom: 24px;
|
||||||
|
.video-item {
|
||||||
|
min-width: 300px !important;
|
||||||
|
p#vi-title {
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.category-end::-webkit-scrollbar {
|
||||||
|
background: transparent;
|
||||||
|
height: 6px;
|
||||||
|
}
|
||||||
|
.category-end::-webkit-scrollbar-thumb {
|
||||||
|
background: transparent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -43,7 +43,7 @@ const Channel = await fetch("https://yt.sudovanilla.org/api/v1/channels/UCY1kMZp
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss" is:global is:inline>
|
||||||
@keyframes wave-lines {
|
@keyframes wave-lines {
|
||||||
0% {
|
0% {
|
||||||
background-position: -468px 0;
|
background-position: -468px 0;
|
||||||
|
|
21
src/pages/categories.astro
Normal file
21
src/pages/categories.astro
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
---
|
||||||
|
import Base from '@layouts/Default.astro'
|
||||||
|
import Video from '@components/Video.astro'
|
||||||
|
import Category from '@components/Category.astro'
|
||||||
|
import CategorySkeleton from '@components/CategorySkeleton.astro'
|
||||||
|
---
|
||||||
|
|
||||||
|
<Base Title="Server Island">
|
||||||
|
<Category Name="Trending" CategoryType="" server:defer>
|
||||||
|
<CategorySkeleton slot='fallback'/>
|
||||||
|
</Category>
|
||||||
|
<Category Name="Movies" CategoryType="movies" server:defer>
|
||||||
|
<CategorySkeleton slot='fallback'/>
|
||||||
|
</Category>
|
||||||
|
<Category Name="Music" CategoryType="music" server:defer>
|
||||||
|
<CategorySkeleton slot='fallback'/>
|
||||||
|
</Category>
|
||||||
|
<Category Name="Gaming" CategoryType="gaming" server:defer>
|
||||||
|
<CategorySkeleton slot='fallback'/>
|
||||||
|
</Category>
|
||||||
|
</Base>
|
Reference in a new issue