Implement sidebar Comment Carousel

This commit is contained in:
Jorge Vargas 2025-02-16 14:15:31 -06:00
parent 56c56c9877
commit fd696a59b4
4 changed files with 98 additions and 0 deletions

View file

@ -11,6 +11,7 @@ import SidebarSection from './sidebar/SidebarSection.astro'
import Highlight from './sidebar/Highlight.astro' import Highlight from './sidebar/Highlight.astro'
import AlbumBox from './AlbumBox.astro' import AlbumBox from './AlbumBox.astro'
import AlbumCount from './sidebar/AlbumCount.astro' import AlbumCount from './sidebar/AlbumCount.astro'
import CommentCarousel from './sidebar/CommentCarousel.astro'
const listClass = const listClass =
'uppercase text-3xl font-semibold w-full text-center py-3 hover:bg-dark-hover hover:text-cyan-400 hover:underline' 'uppercase text-3xl font-semibold w-full text-center py-3 hover:bg-dark-hover hover:text-cyan-400 hover:underline'
@ -48,6 +49,9 @@ const listClass =
<AlbumBox loading /> <AlbumBox loading />
</SidebarSection> </SidebarSection>
</Highlight> </Highlight>
<CommentCarousel>
<SidebarSection slot='fallback' class='h-24 animate-pulse' />
</CommentCarousel>
<AlbumCount server:defer> <AlbumCount server:defer>
<SidebarSection slot='fallback' class='h-32 animate-pulse' /> <SidebarSection slot='fallback' class='h-32 animate-pulse' />
</AlbumCount> </AlbumCount>

View file

@ -0,0 +1,27 @@
---
import prismaClient from 'utils/prisma-client'
import { Icon } from 'astro-icon/components'
import SidebarSection from './SidebarSection.astro'
import Looper from './CommentCarousel/Looper'
const comments = await prismaClient.comments.findMany({
select: { text: true, albums: { select: { id: true, title: true } } },
orderBy: { createdAt: 'desc' },
take: 5
})
---
<SidebarSection>
<Looper comments={comments} client:only='react'>
<Icon name='arrow-right' slot='arrowRight' class='group-hover:fill-black' height={30} width={15} fill='white' />
<Icon
name='arrow-right'
slot='arrowLeft'
class='group-hover:fill-black scale-x-[-1]'
height={30}
width={15}
fill='white'
/>
</Looper>
</SidebarSection>

View file

@ -0,0 +1,58 @@
import clsx from 'clsx'
import { useEffect, useRef, useState, type ButtonHTMLAttributes, type ReactNode } from 'react'
interface Props {
comments: {
text: string | null
albums: {
id: number
title: string | null
} | null
}[]
}
function ArrowButton(props: ButtonHTMLAttributes<HTMLButtonElement>) {
const { className, ...rest } = props
return <button className={clsx('flex-0 px-2 py-2 border rounded-md hover:bg-white group', className)} {...rest} />
}
export default function Looper(props: Props) {
//@ts-ignore
const { comments, arrowRight, arrowLeft } = props
const [index, setIndex] = useState(0)
const timeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null)
const nextIndex = index === comments.length - 1 ? 0 : index + 1
const pastIndex = index === 0 ? comments.length - 1 : index - 1
const isMultiple = comments.length >= 2
const comment = comments[index]
useEffect(() => {
if (timeoutRef.current) clearTimeout(timeoutRef.current)
timeoutRef.current = setTimeout(() => setIndex(nextIndex), 10 * 1000)
}, [index])
return (
<div className='text-md/6 font-extralight'>
<div>{comment.text}</div>
<div className='mt-1'>
-{' '}
<a href={`/album/${comment.albums?.id}`} className='hover:text-hover-link hover:underline'>
{comment.albums?.title}
</a>
</div>
{isMultiple ? (
<div className='flex mt-2.5'>
<ArrowButton onClick={() => setIndex(pastIndex)}>{arrowLeft}</ArrowButton>
<div className='flex-1 text-center content-center'>
{index + 1} / {comments.length}
</div>
<ArrowButton onClick={() => setIndex(nextIndex)}>{arrowRight}</ArrowButton>
</div>
) : (
false
)}
</div>
)
}

View file

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
<svg fill="#000000" height="800px" width="800px" version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
viewBox="0 0 330 330" xml:space="preserve">
<path id="XMLID_222_" d="M250.606,154.389l-150-149.996c-5.857-5.858-15.355-5.858-21.213,0.001
c-5.857,5.858-5.857,15.355,0.001,21.213l139.393,139.39L79.393,304.394c-5.857,5.858-5.857,15.355,0.001,21.213
C82.322,328.536,86.161,330,90,330s7.678-1.464,10.607-4.394l149.999-150.004c2.814-2.813,4.394-6.628,4.394-10.606
C255,161.018,253.42,157.202,250.606,154.389z"/>
</svg>

After

Width:  |  Height:  |  Size: 698 B