Changeset 9c1dcc7 for frontend/src/pages/LandingPage.tsx
- Timestamp:
- 02/07/26 19:52:09 (5 months ago)
- Branches:
- main
- Children:
- 8675f75
- Parents:
- 8a47b30
- File:
-
- 1 edited
-
frontend/src/pages/LandingPage.tsx (modified) (5 diffs)
Legend:
- Unmodified
- Added
- Removed
-
frontend/src/pages/LandingPage.tsx
r8a47b30 r9c1dcc7 1 1 import { useEffect, useRef, useState } from "react"; 2 import { useNavigate } from "react-router-dom"; 2 3 import axiosInstance from "../api/axiosInstance"; 3 4 import AlbumResult from "../components/search/AlbumResult"; 4 5 import SongResult from "../components/search/SongResult"; 5 6 import UserResult from "../components/search/UserResult"; 7 import { usePlayer } from "../context/playerContext"; 6 8 import type { 7 9 Album, … … 11 13 } from "../utils/types"; 12 14 15 // Convert a regular YouTube URL to an embeddable URL 16 const toEmbedUrl = (url: string): string => { 17 try { 18 const parsed = new URL(url); 19 if ( 20 (parsed.hostname === "www.youtube.com" || 21 parsed.hostname === "youtube.com") && 22 parsed.searchParams.has("v") 23 ) { 24 return `https://www.youtube.com/embed/${parsed.searchParams.get("v")}`; 25 } 26 if (parsed.hostname === "youtu.be") { 27 return `https://www.youtube.com/embed${parsed.pathname}`; 28 } 29 return url; 30 } catch { 31 return url; 32 } 33 }; 34 13 35 const CATEGORIES: { value: SearchCategory; label: string }[] = [ 14 36 { value: "songs", label: "Songs" }, … … 19 41 20 42 const LandingPage = () => { 43 const navigate = useNavigate(); 44 const { play, currentSong } = usePlayer(); 21 45 const [songs, setSongs] = useState<Song[]>([]); 22 46 const [loading, setLoading] = useState<boolean>(true); … … 327 351 <div 328 352 key={song.id} 353 onClick={() => navigate(`/songs/${song.id}`)} 329 354 className="bg-[#282828] rounded-xl overflow-hidden cursor-pointer shadow-lg transition-all duration-300 ease-in-out hover:-translate-y-2 hover:shadow-2xl group" 330 355 > … … 340 365 /> 341 366 <div className="absolute top-0 left-0 w-full h-full bg-black/60 flex items-center justify-center opacity-0 group-hover:opacity-100 transition-opacity duration-300"> 342 <div className="w-15 h-15 rounded-full bg-[#1db954] flex items-center justify-center text-2xl text-black shadow-[0_4px_12px_rgba(29,185,84,0.5)]"> 343 ▶ 344 </div> 367 {song.link ? ( 368 <button 369 onClick={(e) => { 370 e.stopPropagation(); 371 play({ 372 id: song.id, 373 title: song.title, 374 artist: song.releasedBy, 375 cover: song.cover, 376 embedUrl: toEmbedUrl(song.link!), 377 }); 378 }} 379 className={`w-14 h-14 rounded-full flex items-center justify-center text-xl shadow-[0_4px_12px_rgba(29,185,84,0.5)] transition-all cursor-pointer ${ 380 currentSong?.id === song.id 381 ? "bg-white text-[#1db954]" 382 : "bg-[#1db954] text-black hover:scale-105" 383 }`} 384 aria-label={ 385 currentSong?.id === song.id 386 ? "Now playing" 387 : "Play song" 388 } 389 > 390 {currentSong?.id === song.id ? ( 391 <svg 392 className="w-6 h-6" 393 fill="currentColor" 394 viewBox="0 0 24 24" 395 > 396 <path d="M6 19h4V5H6v14zm8-14v14h4V5h-4z" /> 397 </svg> 398 ) : ( 399 <svg 400 className="w-6 h-6" 401 fill="currentColor" 402 viewBox="0 0 24 24" 403 > 404 <path d="M8 5v14l11-7z" /> 405 </svg> 406 )} 407 </button> 408 ) : ( 409 <div className="w-14 h-14 rounded-full bg-[#1db954] flex items-center justify-center text-xl text-black shadow-[0_4px_12px_rgba(29,185,84,0.5)]"> 410 ▶ 411 </div> 412 )} 345 413 </div> 346 414 </div>
Note:
See TracChangeset
for help on using the changeset viewer.
