Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
85 changes: 65 additions & 20 deletions src/components/Player.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,14 @@ import { usePlayerStore } from "@/store/playerStore"
import { useEffect, useRef, useState } from "react"
import { Slider } from "./Slider"


export const Prev = () => (
<svg fill="currentColor" role="img" height="16" width="16" aria-hidden="true" viewBox="0 0 16 16"><path d="M3.3 1a.7.7 0 0 1 .7.7v5.15l9.95-5.744a.7.7 0 0 1 1.05.606v12.575a.7.7 0 0 1-1.05.607L4 9.149V14.3a.7.7 0 0 1-.7.7H1.7a.7.7 0 0 1-.7-.7V1.7a.7.7 0 0 1 .7-.7h1.6z"></path></svg>
)
export const Next = () => (
<svg fill="currentColor" role="img" height="16" width="16" aria-hidden="true" viewBox="0 0 16 16"><path d="M12.7 1a.7.7 0 0 0-.7.7v5.15L2.05 1.107A.7.7 0 0 0 1 1.712v12.575a.7.7 0 0 0 1.05.607L12 9.149V14.3a.7.7 0 0 0 .7.7h1.6a.7.7 0 0 0 .7-.7V1.7a.7.7 0 0 0-.7-.7h-1.6z"></path></svg>
)

export const Pause = ({ className }) => (
<svg className={className} role="img" height="16" width="16" aria-hidden="true" viewBox="0 0 16 16"><path d="M2.7 1a.7.7 0 0 0-.7.7v12.6a.7.7 0 0 0 .7.7h2.6a.7.7 0 0 0 .7-.7V1.7a.7.7 0 0 0-.7-.7H2.7zm8 0a.7.7 0 0 0-.7.7v12.6a.7.7 0 0 0 .7.7h2.6a.7.7 0 0 0 .7-.7V1.7a.7.7 0 0 0-.7-.7h-2.6z"></path></svg>
)
Expand All @@ -12,11 +20,11 @@ export const Play = ({ className }) => (

export const VolumeSilence = () => (
<svg fill="currentColor" role="presentation" height="16" width="16" aria-hidden="true" aria-label="Volumen apagado" viewBox="0 0 16 16" ><path d="M13.86 5.47a.75.75 0 0 0-1.061 0l-1.47 1.47-1.47-1.47A.75.75 0 0 0 8.8 6.53L10.269 8l-1.47 1.47a.75.75 0 1 0 1.06 1.06l1.47-1.47 1.47 1.47a.75.75 0 0 0 1.06-1.06L12.39 8l1.47-1.47a.75.75 0 0 0 0-1.06z"></path><path d="M10.116 1.5A.75.75 0 0 0 8.991.85l-6.925 4a3.642 3.642 0 0 0-1.33 4.967 3.639 3.639 0 0 0 1.33 1.332l6.925 4a.75.75 0 0 0 1.125-.649v-1.906a4.73 4.73 0 0 1-1.5-.694v1.3L2.817 9.852a2.141 2.141 0 0 1-.781-2.92c.187-.324.456-.594.78-.782l5.8-3.35v1.3c.45-.313.956-.55 1.5-.694V1.5z"></path></svg>
)
)

export const Volume = () => (
<svg fill="currentColor" role="presentation" height="16" width="16" aria-hidden="true" aria-label="Volumen alto" id="volume-icon" viewBox="0 0 16 16"><path d="M9.741.85a.75.75 0 0 1 .375.65v13a.75.75 0 0 1-1.125.65l-6.925-4a3.642 3.642 0 0 1-1.33-4.967 3.639 3.639 0 0 1 1.33-1.332l6.925-4a.75.75 0 0 1 .75 0zm-6.924 5.3a2.139 2.139 0 0 0 0 3.7l5.8 3.35V2.8l-5.8 3.35zm8.683 4.29V5.56a2.75 2.75 0 0 1 0 4.88z"></path><path d="M11.5 13.614a5.752 5.752 0 0 0 0-11.228v1.55a4.252 4.252 0 0 1 0 8.127v1.55z"></path></svg>
)
)

const CurrentSong = ({ image, title, artists }) => {
return (
Expand All @@ -25,18 +33,18 @@ const CurrentSong = ({ image, title, artists }) => {
flex items-center gap-5 relative
overflow-hidden
`}>
<picture className="w-16 h-16 bg-zinc-800 rounded-md shadow-lg overflow-hidden">
<img src={image} alt={title} />
</picture>

<div className="flex flex-col">
<h3 className="font-semibold text-sm block">
{title}
</h3>
<span className="text-xs opacity-80">
{artists?.join(', ')}
</span>
</div>
<picture className="w-16 h-16 bg-zinc-800 rounded-md shadow-lg overflow-hidden">
<img src={image} alt={title} />
</picture>

<div className="flex flex-col">
<h3 className="font-semibold text-sm block">
{title}
</h3>
<span className="text-xs opacity-80">
{artists?.join(', ')}
</span>
</div>

</div>
)
Expand Down Expand Up @@ -113,7 +121,7 @@ const VolumeControl = () => {
<button className="opacity-70 hover:opacity-100 transition" onClick={handleClickVolumen}>
{isVolumeSilenced ? <VolumeSilence /> : <Volume />}
</button>

<Slider
defaultValue={[100]}
max={100}
Expand All @@ -130,8 +138,8 @@ const VolumeControl = () => {
)
}

export function Player () {
const { currentMusic, isPlaying, setIsPlaying, volume } = usePlayerStore(state => state)
export function Player() {
const { currentMusic, setCurrentMusic, isPlaying, setIsPlaying, volume } = usePlayerStore(state => state)
const audioRef = useRef()

useEffect(() => {
Expand All @@ -158,6 +166,32 @@ export function Player () {
setIsPlaying(!isPlaying)
}

const getSongIndex = (id) => {
return currentMusic.songs.findIndex(e => e.id === id) ?? -1
}

const onNextSong = () => {
const { song, playlist, songs } = currentMusic;
const index = getSongIndex(song.id)
if (index > -1 && index + 1 < songs.length) {
setIsPlaying(false);
setCurrentMusic({ songs, playlist, song: songs[index + 1] })
setIsPlaying(true);
}
}

const onPrevSong = () => {

const { song, playlist, songs } = currentMusic;
const index = getSongIndex(song.id)
if (index > -1 && index > 0) {
setIsPlaying(false);
setCurrentMusic({ songs, playlist, song: songs[index - 1] })
setIsPlaying(true);
}
}


return (
<div className="flex flex-row justify-between w-full px-1 z-50">
<div className="w-[200px]">
Expand All @@ -166,9 +200,20 @@ export function Player () {

<div className="grid place-content-center gap-4 flex-1">
<div className="flex justify-center flex-col items-center">
<button className="bg-white rounded-full p-2" onClick={handleClick}>
{isPlaying ? <Pause /> : <Play />}
</button>
<div className="flex gap-8">
<button onClick={onPrevSong} title="Prev">
<Prev />
</button>
<button
title="Play / Pause"
onClick={handleClick}
className="bg-white rounded-full p-2">
{isPlaying ? <Pause /> : <Play />}
</button>
<button onClick={onNextSong} title="Next">
<Next />
</button>
</div>
<SongControl audio={audioRef} />
<audio ref={audioRef} />
</div>
Expand Down