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/Sidebar.tsx

    r8a47b30 r9c1dcc7  
    11import { useEffect, useState } from "react";
     2import { useNavigate } from "react-router-dom";
    23import axiosInstance from "../api/axiosInstance";
    34import { useAuth } from "../context/authContext";
     5import { usePlayer } from "../context/playerContext";
    46import type { BasicPlaylist, BasicSong, SidebarProps } from "../utils/types";
     7
     8const toEmbedUrl = (url: string): string => {
     9        try {
     10                const parsed = new URL(url);
     11                if (
     12                        (parsed.hostname === "www.youtube.com" ||
     13                                parsed.hostname === "youtube.com") &&
     14                        parsed.searchParams.has("v")
     15                ) {
     16                        return `https://www.youtube.com/embed/${parsed.searchParams.get("v")}`;
     17                }
     18                if (parsed.hostname === "youtu.be") {
     19                        return `https://www.youtube.com/embed${parsed.pathname}`;
     20                }
     21                return url;
     22        } catch {
     23                return url;
     24        }
     25};
    526
    627const Sidebar = ({ isOpen, onClose }: SidebarProps) => {
    728        const { user } = useAuth();
     29        const navigate = useNavigate();
     30        const { play, currentSong } = usePlayer();
    831        const [recentlyListened, setRecentlyListened] = useState<BasicSong[]>([]);
    932        const [playlists, setPlaylists] = useState<BasicPlaylist[]>([]);
     
    7497                                                        <div
    7598                                                                key={song.id}
    76                                                                 className="flex items-center gap-3 p-2 rounded-lg hover:bg-white/5 cursor-pointer transition-colors"
     99                                                                onClick={() => navigate(`/songs/${song.id}`)}
     100                                                                className="flex items-center gap-3 p-2 rounded-lg hover:bg-white/5 cursor-pointer transition-colors group relative"
    77101                                                        >
    78102                                                                <img
     
    80104                                                                        alt={song.title}
    81105                                                                        className="w-10 h-10 rounded object-cover"
     106                                                                        onError={(e) => {
     107                                                                                (e.target as HTMLImageElement).src = "/favicon.png";
     108                                                                        }}
    82109                                                                />
    83110                                                                <div className="flex-1 min-w-0">
     
    89116                                                                        </p>
    90117                                                                </div>
     118                                                                {song.link && (
     119                                                                        <button
     120                                                                                onClick={(e) => {
     121                                                                                        e.stopPropagation();
     122                                                                                        play({
     123                                                                                                id: song.id,
     124                                                                                                title: song.title,
     125                                                                                                artist: song.artist,
     126                                                                                                cover: song.cover,
     127                                                                                                embedUrl: toEmbedUrl(song.link!),
     128                                                                                        });
     129                                                                                }}
     130                                                                                className={`p-1.5 rounded-full transition-all opacity-0 group-hover:opacity-100 ${
     131                                                                                        currentSong?.id === song.id
     132                                                                                                ? "bg-white text-[#1db954]"
     133                                                                                                : "bg-[#1db954] text-black hover:scale-110"
     134                                                                                }`}
     135                                                                                aria-label={
     136                                                                                        currentSong?.id === song.id ? "Now playing" : "Play song"
     137                                                                                }
     138                                                                        >
     139                                                                                {currentSong?.id === song.id ? (
     140                                                                                        <svg
     141                                                                                                className="w-4 h-4"
     142                                                                                                fill="currentColor"
     143                                                                                                viewBox="0 0 24 24"
     144                                                                                        >
     145                                                                                                <path d="M6 19h4V5H6v14zm8-14v14h4V5h-4z" />
     146                                                                                        </svg>
     147                                                                                ) : (
     148                                                                                        <svg
     149                                                                                                className="w-4 h-4"
     150                                                                                                fill="currentColor"
     151                                                                                                viewBox="0 0 24 24"
     152                                                                                        >
     153                                                                                                <path d="M8 5v14l11-7z" />
     154                                                                                        </svg>
     155                                                                                )}
     156                                                                        </button>
     157                                                                )}
    91158                                                        </div>
    92159                                                ))}
Note: See TracChangeset for help on using the changeset viewer.