Skip to content
Open
Show file tree
Hide file tree
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
1 change: 0 additions & 1 deletion apps/client/src/components/track-player/youtube-player.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import React from 'react';
import ReactPlayer from 'react-player';

const YoutubePlayer = ({ videoId }: Readonly<{ videoId: string }>) => {
Expand Down
30 changes: 13 additions & 17 deletions apps/client/src/components/track-upload-wrapper/youtube-search.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
import { useState, useEffect, useCallback } from 'react';
import { Search, PlayCircle, Loader2, ExternalLink, Plus } from 'lucide-react';
import { createProjectFromYouTube, extractLyricsFromVideo, searchYouTube, type YouTubeSearchResult } from '@/data/api';
import { cn, extractVideoId, isValidYoutubeUrl, parseYouTubeDuration } from '@/lib/utils';
import { ExternalLink, Loader2, PlayCircle, Plus, Search } from 'lucide-react';
import { AnimatePresence, motion } from 'motion/react';
import { useCallback, useEffect, useState } from 'react';
import { toast } from 'sonner';
import { Badge } from '../ui/badge';
import { Button } from '../ui/button';
import { Input } from '../ui/input';
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '../ui/card';
import { Badge } from '../ui/badge';
import { Tabs, TabsList, TabsTrigger } from '../ui/tabs';
import { isValidYoutubeUrl, extractVideoId, cn, parseYouTubeDuration } from '@/lib/utils';
import { motion, AnimatePresence } from 'motion/react';
import { searchYouTube, createProjectFromYouTube, extractLyricsFromVideo, type YouTubeSearchResult } from '@/data/api';
import { toast } from 'sonner';
import { Input } from '../ui/input';

type YouTubeSearchProps = {
onVideoSelect?: (video: YouTubeSearchResult) => void;
Expand All @@ -22,10 +21,9 @@
const [addingToPlaylist, setAddingToPlaylist] = useState<string | null>(null);
const [error, setError] = useState<string | null>(null);
const [hasSearched, setHasSearched] = useState(false);
const [searchType, setSearchType] = useState<'url' | 'title'>('url');

// Debounced search function
const performSearch = useCallback(async (query: string, type: 'url' | 'title') => {
const performSearch = useCallback(async (query: string) => {
if (!query.trim()) {
setSearchResults([]);
setHasSearched(false);
Expand Down Expand Up @@ -78,11 +76,11 @@
}

const debounceTimer = setTimeout(() => {
performSearch(searchQuery, searchType);
performSearch(searchQuery);

Check warning on line 79 in apps/client/src/components/track-upload-wrapper/youtube-search.tsx

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

apps/client/src/components/track-upload-wrapper/youtube-search.tsx#L79

Promises must be awaited, end with a call to .catch, end with a call to .then with a rejection handler or be explicitly marked as ignored with the `void` operator.
}, 500); // 500ms delay

return () => clearTimeout(debounceTimer);
}, [searchQuery, searchType, performSearch]);
}, [searchQuery, performSearch]);



Expand All @@ -96,7 +94,7 @@

try {
// Create project from YouTube video
const projectResult = await createProjectFromYouTube(video);
await createProjectFromYouTube(video);

// Extract lyrics if available
try {
Expand Down Expand Up @@ -134,9 +132,7 @@
<div className="relative">
<Search className={`absolute left-3 top-1/2 transform -translate-y-1/2 h-4 w-4 ${isSearching ? 'text-primary animate-pulse' : 'text-muted-foreground'}`} />
<Input
placeholder={searchType === 'title'
? "Search by song title (e.g., 'Shake It Off', 'Bohemian Rhapsody')..."
: "Search for songs or paste YouTube URL..."
placeholder={ "Search by song title (e.g., 'Shake It Off', 'Bohemian Rhapsody')..."
}
value={searchQuery}
onChange={(e) => setSearchQuery(e.target.value)}
Expand Down