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
4 changes: 3 additions & 1 deletion App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,13 @@ import { List } from 'lucide-react';
import { PlaylistDetail } from './components/PlaylistDetail';
import { Toast, ToastType } from './components/Toast';
import { SearchPage } from './components/SearchPage';
import { useTranslation } from 'react-i18next';


export default function App() {
// Responsive
const { isMobile, isDesktop } = useResponsive();
const { t } = useTranslation();

// Auth
const { user, token, isAuthenticated, isLoading: authLoading, setupUser, logout } = useAuth();
Expand Down Expand Up @@ -1286,7 +1288,7 @@ export default function App() {
onClick={() => setMobileShowList(!mobileShowList)}
className="bg-zinc-800 text-white px-4 py-2 rounded-full shadow-lg border border-white/10 flex items-center gap-2 text-sm font-bold"
>
{mobileShowList ? 'Create Song' : 'View List'}
{mobileShowList ? t('common.createSong') : t('common.viewList')}
<List size={16} />
</button>
</div>
Expand Down
292 changes: 142 additions & 150 deletions components/CreatePanel.tsx

Large diffs are not rendered by default.

30 changes: 16 additions & 14 deletions components/LibraryView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { useAuth } from '../context/AuthContext';
import { SongDropdownMenu } from './SongDropdownMenu';
import { ShareModal } from './ShareModal';
import { AlbumCover } from './AlbumCover';
import { useTranslation } from 'react-i18next';

interface LibraryViewProps {
allSongs: Song[];
Expand Down Expand Up @@ -47,6 +48,7 @@ export const LibraryView: React.FC<LibraryViewProps> = ({
onDeleteReferenceTrack,
}) => {
const { user } = useAuth();
const { t } = useTranslation();
const [activeTab, setActiveTab] = useState<'all' | 'playlists' | 'liked' | 'uploads'>('all');
const [shareModalOpen, setShareModalOpen] = useState(false);
const [shareSong, setShareSong] = useState<Song | null>(null);
Expand All @@ -67,13 +69,13 @@ export const LibraryView: React.FC<LibraryViewProps> = ({
<>
<div className="flex-1 bg-white dark:bg-black overflow-y-auto custom-scrollbar p-6 lg:p-10 pb-32 transition-colors duration-300">
<div className="flex items-center justify-between mb-8">
<h1 className="text-3xl font-bold text-zinc-900 dark:text-white">Your Library</h1>
<h1 className="text-3xl font-bold text-zinc-900 dark:text-white">{t('library.title')}</h1>
<button
onClick={onCreatePlaylist}
className="flex items-center gap-2 bg-zinc-900 dark:bg-zinc-800 hover:bg-zinc-800 dark:hover:bg-zinc-700 text-white px-4 py-2 rounded-full font-medium transition-colors shadow-lg shadow-zinc-900/10 dark:shadow-none"
>
<Plus size={18} />
<span>New Playlist</span>
<span>{t('library.newPlaylist')}</span>
</button>
</div>

Expand All @@ -83,28 +85,28 @@ export const LibraryView: React.FC<LibraryViewProps> = ({
onClick={() => setActiveTab('all')}
className={`pb-3 text-sm font-bold transition-colors relative ${activeTab === 'all' ? 'text-zinc-900 dark:text-white' : 'text-zinc-500 hover:text-zinc-900 dark:hover:text-white'}`}
>
All Songs
{t('library.tabs.all')}
{activeTab === 'all' && <div className="absolute bottom-0 left-0 right-0 h-0.5 bg-green-500 rounded-full"></div>}
</button>
<button
onClick={() => setActiveTab('liked')}
className={`pb-3 text-sm font-bold transition-colors relative ${activeTab === 'liked' ? 'text-zinc-900 dark:text-white' : 'text-zinc-500 hover:text-zinc-900 dark:hover:text-white'}`}
>
Liked Songs
{t('library.tabs.liked')}
{activeTab === 'liked' && <div className="absolute bottom-0 left-0 right-0 h-0.5 bg-green-500 rounded-full"></div>}
</button>
<button
onClick={() => setActiveTab('playlists')}
className={`pb-3 text-sm font-bold transition-colors relative ${activeTab === 'playlists' ? 'text-zinc-900 dark:text-white' : 'text-zinc-500 hover:text-zinc-900 dark:hover:text-white'}`}
>
Playlists
{t('library.tabs.playlists')}
{activeTab === 'playlists' && <div className="absolute bottom-0 left-0 right-0 h-0.5 bg-green-500 rounded-full"></div>}
</button>
<button
onClick={() => setActiveTab('uploads')}
className={`pb-3 text-sm font-bold transition-colors relative ${activeTab === 'uploads' ? 'text-zinc-900 dark:text-white' : 'text-zinc-500 hover:text-zinc-900 dark:hover:text-white'}`}
>
Uploads
{t('library.tabs.uploads')}
{activeTab === 'uploads' && <div className="absolute bottom-0 left-0 right-0 h-0.5 bg-green-500 rounded-full"></div>}
</button>
</div>
Expand All @@ -113,7 +115,7 @@ export const LibraryView: React.FC<LibraryViewProps> = ({
{activeTab === 'all' && (
<div className="space-y-1">
{allSongs.length === 0 ? (
<div className="text-sm text-zinc-500 dark:text-zinc-400">No songs yet.</div>
<div className="text-sm text-zinc-500 dark:text-zinc-400">{t('library.empty.songs')}</div>
) : (
allSongs.map((song, idx) => (
<div key={song.id} className="group flex items-center gap-4 p-2 rounded hover:bg-zinc-100 dark:hover:bg-white/10 transition-colors" onClick={() => onPlaySong(song, allSongs)}>
Expand Down Expand Up @@ -168,10 +170,10 @@ export const LibraryView: React.FC<LibraryViewProps> = ({
<Heart fill="white" size={64} className="text-white" />
</div>
<div className="mb-2">
<h2 className="text-sm font-bold uppercase text-zinc-500 dark:text-white mb-2">Playlist</h2>
<h1 className="text-5xl font-extrabold text-zinc-900 dark:text-white mb-4">Liked Songs</h1>
<h2 className="text-sm font-bold uppercase text-zinc-500 dark:text-white mb-2">{t('common.playlist')}</h2>
<h1 className="text-5xl font-extrabold text-zinc-900 dark:text-white mb-4">{t('library.likedSongs')}</h1>
<div className="text-sm text-zinc-500 dark:text-zinc-300 font-medium">
{likedSongs.length} songs
{t('common.songCount', { count: likedSongs.length })}
</div>
</div>
<div className="ml-auto mb-2 opacity-0 group-hover:opacity-100 transition-opacity">
Expand Down Expand Up @@ -241,15 +243,15 @@ export const LibraryView: React.FC<LibraryViewProps> = ({
)}
</div>
<h3 className="font-bold text-zinc-900 dark:text-white truncate">{playlist.name}</h3>
<p className="text-sm text-zinc-500 dark:text-zinc-400 line-clamp-2">{playlist.description || `By You`}</p>
<p className="text-sm text-zinc-500 dark:text-zinc-400 line-clamp-2">{playlist.description || t('common.byYou')}</p>
</div>
))}
</div>
)}
{activeTab === 'uploads' && (
<div className="space-y-2">
{referenceTracks.length === 0 ? (
<div className="text-sm text-zinc-500 dark:text-zinc-400">No uploads yet.</div>
<div className="text-sm text-zinc-500 dark:text-zinc-400">{t('library.empty.uploads')}</div>
) : (
referenceTracks.map((track) => (
<div key={track.id} className="flex items-center gap-4 p-3 rounded-lg border border-zinc-200 dark:border-white/5 bg-white dark:bg-zinc-900/40">
Expand All @@ -265,7 +267,7 @@ export const LibraryView: React.FC<LibraryViewProps> = ({
<button
className="p-2 rounded-full hover:bg-zinc-200 dark:hover:bg-white/5 text-zinc-500 hover:text-red-600 transition-colors"
onClick={() => onDeleteReferenceTrack?.(track.id)}
title="Delete upload"
title={t('actions.deleteUpload')}
>
<Trash2 size={16} />
</button>
Expand All @@ -284,4 +286,4 @@ export const LibraryView: React.FC<LibraryViewProps> = ({
)}
</>
);
};
};
Loading