Skip to content

Commit

Permalink
Merge pull request #8 from lberoiza/main
Browse files Browse the repository at this point in the history
Agrega lista con nuevas funcionalidades al proyecto Spotfy-Clone
  • Loading branch information
midudev authored Nov 24, 2024
2 parents d202f4c + 2acedc8 commit e0a537b
Show file tree
Hide file tree
Showing 29 changed files with 641 additions and 309 deletions.
5 changes: 5 additions & 0 deletions .idea/.gitignore

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions .idea/codeStyles/codeStyleConfig.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions .idea/modules.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 12 additions & 0 deletions .idea/spotify-twitch-clone.iml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions .idea/vcs.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

28 changes: 14 additions & 14 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
{
"dependencies": {
"@astrojs/react": "3.0.2",
"@astrojs/svelte": "4.0.2",
"@astrojs/tailwind": "5.0.0",
"@astrojs/vercel": "5.0.2",
"@radix-ui/react-slider": "^1.1.2",
"@types/react": "18.0.21",
"@astrojs/react": "3.0.9",
"@astrojs/svelte": "5.0.3",
"@astrojs/tailwind": "5.1.0",
"@astrojs/vercel": "6.1.2",
"@radix-ui/react-slider": "1.1.2",
"@types/react": "18.2.46",
"@types/react-dom": "18.0.6",
"astro": "3.2.2",
"clsx": "^2.0.0",
"react": "18.0.0",
"react-dom": "18.0.0",
"svelte": "4.0.0",
"tailwindcss": "3.0.24",
"zustand": "^4.4.3"
"astro": "^4.2.4",
"clsx": "2.1.0",
"react": "18.2.0",
"react-dom": "18.2.0",
"svelte": "4.2.8",
"tailwindcss": "3.4.0",
"zustand": "4.4.3"
},
"name": "spotify-twitch-clone",
"scripts": {
Expand All @@ -25,4 +25,4 @@
},
"type": "module",
"version": "0.0.1"
}
}
38 changes: 0 additions & 38 deletions src/components/CardPlayButton.jsx

This file was deleted.

40 changes: 40 additions & 0 deletions src/components/CardPlayButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { usePlayerStore } from '@/store/playerStore'
import { getPlayListInfoById } from "@/services/ApiService";
import { Pause, Play } from "@/icons/PlayerIcons"


export function CardPlayButton({id, size = 'small'}) {
const {
currentMusic,
isPlaying,
setIsPlaying,
setCurrentMusic
} = usePlayerStore(state => state)

const isPlayingPlaylist = isPlaying && currentMusic?.playlist?.id === id
const isThisPlaylistInStore = currentMusic?.playlist?.id === id

const handleClick = () => {
if (isThisPlaylistInStore) {
setIsPlaying(!isPlaying);
return
}

getPlayListInfoById(id).then(data => {
const {songs, playlist} = data
setCurrentMusic({songs: songs, playlist: playlist, song: songs[0]})
}).then(() => {
setIsPlaying(true);
})
}

const iconClassName = size === 'small' ? 'w-4 h-4' : 'w-5 h-5'


return (
<button onClick={handleClick}
className="card-play-button rounded-full text-black bg-green-500 p-4 hover:scale-105 transition hover:bg-green-400">
{isPlayingPlaylist ? <Pause className={iconClassName}/> : <Play className={iconClassName}/>}
</button>
)
}
43 changes: 0 additions & 43 deletions src/components/MusicsTable.astro

This file was deleted.

66 changes: 66 additions & 0 deletions src/components/MusicsTable.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import {type Song} from "@/lib/data"
import {TimeIcon} from "@/icons/MusicsTableIcons"
import {MusicsTablePlay} from "@/components/MusicsTablePlay"
import {usePlayerStore} from "../store/playerStore";

interface Props {
songs: Song[]
}


const isCurrentSong = (song: Song) => {
const {song: currentSong, playlist} = usePlayerStore(state => state.currentMusic)
return currentSong?.id == song.id && playlist?.albumId == song.albumId
}


export const MusicsTable = ({songs}: Props) => {
return (
<table className="table-auto text-left min-w-full divide-y divide-gray-500/20">
<thead className="">
<tr className="text-zinc-400 text-sm">
<th className="px-4 py-2 font-light">#</th>
<th className="px-4 py-2 font-light">Título</th>
<th className="px-4 py-2 font-light">Álbum</th>
<th className="px-4 py-2 font-light"><TimeIcon /></th>
</tr>
</thead>

<tbody>
<tr className="h-[16px]"></tr>
{
songs.map((song, index) => {
const isCurrentSongBoolean = isCurrentSong(song)
return (
<tr
key={`{song.albumId}-${song.id}`} className="text-gray-300 border-spacing-0 text-sm font-light hover:bg-white/10 overflow-hidden transition duration-300 group">
<td className="relative px-4 py-2 rounded-tl-lg rounded-bl-lg w-5">
<span className="absolute top-5 opacity-100 transition-all group-hover:opacity-0">{index + 1}</span>
<div className="absolute top-5 opacity-0 transition-all group-hover:opacity-100">
<MusicsTablePlay song={song} isCurrentSong={isCurrentSongBoolean}/>
</div>
</td>
<td className="px-4 py-2 flex gap-3">
<picture className="">
<img src={song.image} alt={song.title} className="w-11 h-11"/>
</picture>
<div className="flex flex-col">
<h3 className={
`text-base font-normal
${isCurrentSongBoolean ? "text-green-400" : "text-White"}
`
}>{song.title}</h3>
<span>{song.artists.join(", ")}</span>
</div>
</td>
<td className="px-4 py-2">{song.album}</td>
<td className="px-4 py-2 rounded-tr-lg rounded-br-lg">{song.duration}</td>
</tr>
)
}
)
}
</tbody>
</table>
);
}
69 changes: 69 additions & 0 deletions src/components/MusicsTablePlay.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import { type Song } from "@/lib/data"
import { Play, Pause } from "@/icons/PlayerIcons";
import { usePlayerStore, type CurrentMusic } from "@/store/playerStore.ts";
import { getPlayListInfoById } from "@/services/ApiService";

interface Props {
song: Song
isCurrentSong: boolean
}


const isNewSongOfAnotherPlaylist = (currentMusic: CurrentMusic, song: Song) => {
return currentMusic.playlist?.id != song.albumId
}


const setNewCurrentMusic = (
song: Song,
setIsPlaying: (isPlaying: boolean) => void,
setCurrentMusic: (currentMusic: CurrentMusic) => void): void => {
getPlayListInfoById(song.albumId).then(data => {
const {songs, playlist} = data
setCurrentMusic({songs: songs, playlist: playlist, song: song})
}).then(() => {
setIsPlaying(true)
});
}

export const MusicsTablePlay = ({song, isCurrentSong}: Props) => {
const {
currentMusic,
isPlaying,
setIsPlaying,
setCurrentMusic
} = usePlayerStore(state => state)

const isCurrentSongRunning = (song: Song) => {
return (currentMusic.song?.id == song.id)
&& (currentMusic.playlist?.albumId == song.albumId)
&& isPlaying
}


const handleClick = (song: Song) => {
if (isCurrentSongRunning(song)) {
setIsPlaying(false)
return
}

if (isNewSongOfAnotherPlaylist(currentMusic, song)) {
setNewCurrentMusic(song, setIsPlaying, setCurrentMusic)
return
}

// the playlist is the same, but the song is different
if (currentMusic.song?.id !== song.id) {
setCurrentMusic({songs: currentMusic.songs, playlist: currentMusic.playlist, song: song})
}
setIsPlaying(true)
}


const className = "hover:scale-125"
return (
<button className="text-white" onClick={() => handleClick(song)}>
{isCurrentSongRunning(song) ? <Pause className={className}/> : <Play className={className}/>}
</button>
)
}
Loading

0 comments on commit e0a537b

Please sign in to comment.