Ignore:
Timestamp:
02/07/26 19:52:09 (5 months ago)
Author:
Filip Gavrilovski <filipgavrilovski28@…>
Branches:
main
Children:
8675f75
Parents:
8a47b30
Message:

add experimental video miniplayer

File:
1 edited

Legend:

Unmodified
Added
Removed
  • frontend/src/components/search/SongResult.tsx

    r8a47b30 r9c1dcc7  
     1import { useNavigate } from "react-router-dom";
     2import { usePlayer } from "../../context/playerContext";
    13import type { Song } from "../../utils/types";
    24
     
    57}
    68
     9const toEmbedUrl = (url: string): string => {
     10        try {
     11                const parsed = new URL(url);
     12                if (
     13                        (parsed.hostname === "www.youtube.com" ||
     14                                parsed.hostname === "youtube.com") &&
     15                        parsed.searchParams.has("v")
     16                ) {
     17                        return `https://www.youtube.com/embed/${parsed.searchParams.get("v")}`;
     18                }
     19                if (parsed.hostname === "youtu.be") {
     20                        return `https://www.youtube.com/embed${parsed.pathname}`;
     21                }
     22                return url;
     23        } catch {
     24                return url;
     25        }
     26};
     27
    728const SongResult = ({ song }: SongResultProps) => {
     29        const navigate = useNavigate();
     30        const { play, currentSong } = usePlayer();
     31
    832        return (
    9                 <div className="flex items-center gap-4 p-3 rounded-lg hover:bg-white/5 cursor-pointer transition-colors group">
     33                <div
     34                        onClick={() => navigate(`/songs/${song.id}`)}
     35                        className="flex items-center gap-4 p-3 rounded-lg hover:bg-white/5 cursor-pointer transition-colors group"
     36                >
    1037                        <img
    1138                                src={song.cover || "/favicon.png"}
     
    2249                                </p>
    2350                        </div>
    24                         <span className="text-xs text-gray-500 uppercase tracking-wider">
     51                        <span className="text-xs text-gray-500 uppercase tracking-wider mr-2">
    2552                                {song.genre}
    2653                        </span>
     54                        {song.link && (
     55                                <button
     56                                        onClick={(e) => {
     57                                                e.stopPropagation();
     58                                                play({
     59                                                        id: song.id,
     60                                                        title: song.title,
     61                                                        artist: song.releasedBy,
     62                                                        cover: song.cover,
     63                                                        embedUrl: toEmbedUrl(song.link!),
     64                                                });
     65                                        }}
     66                                        className={`p-2 rounded-full transition-all opacity-0 group-hover:opacity-100 ${
     67                                                currentSong?.id === song.id
     68                                                        ? "bg-white text-[#1db954]"
     69                                                        : "bg-[#1db954] text-black hover:scale-110"
     70                                        }`}
     71                                        aria-label={currentSong?.id === song.id ? "Now playing" : "Play song"}
     72                                >
     73                                        {currentSong?.id === song.id ? (
     74                                                <svg className="w-5 h-5" fill="currentColor" viewBox="0 0 24 24">
     75                                                        <path d="M6 19h4V5H6v14zm8-14v14h4V5h-4z" />
     76                                                </svg>
     77                                        ) : (
     78                                                <svg className="w-5 h-5" fill="currentColor" viewBox="0 0 24 24">
     79                                                        <path d="M8 5v14l11-7z" />
     80                                                </svg>
     81                                        )}
     82                                </button>
     83                        )}
    2784                </div>
    2885        );
Note: See TracChangeset for help on using the changeset viewer.