feat: Implement offline library management with IndexedDB support

- Added `useOfflineLibrary` hook for managing offline library state and synchronization.
- Created `OfflineLibraryManager` class for handling IndexedDB operations and syncing with Navidrome API.
- Implemented methods for retrieving and storing albums, artists, songs, and playlists.
- Added support for offline favorites management (star/unstar).
- Implemented playlist creation, updating, and deletion functionalities.
- Added search functionality for offline data.
- Created a manifest file for PWA support with icons and shortcuts.
- Added service worker file for caching and offline capabilities.
This commit is contained in:
2025-08-07 22:07:53 +00:00
committed by GitHub
parent af5e24b80e
commit f6a6ee5d2e
23 changed files with 4239 additions and 229 deletions

View File

@@ -24,8 +24,9 @@ import React, { useState, useEffect, useMemo, useCallback } from 'react';
import { Button } from "@/components/ui/button";
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
import { ArtistIcon } from "@/app/components/artist-icon";
import { Heart, Music, Disc, Mic, Play } from "lucide-react";
import { Heart, Music, Disc, Mic, Play, Download } from "lucide-react";
import { Album, Artist, Song } from "@/lib/navidrome";
import { OfflineIndicator } from "@/app/components/OfflineIndicator";
interface AlbumArtworkProps extends React.HTMLAttributes<HTMLDivElement> {
album: Album
@@ -148,6 +149,16 @@ export function AlbumArtwork({
<div className="absolute inset-0 bg-black/50 opacity-0 group-hover:opacity-100 transition-opacity flex items-center justify-center gap-2">
<Play className="w-6 h-6 mx-auto hidden group-hover:block" onClick={() => handlePlayAlbum(album)}/>
</div>
{/* Offline indicator in top-right corner */}
<div className="absolute top-2 right-2">
<OfflineIndicator
id={album.id}
type="album"
size="sm"
className="bg-black/60 text-white rounded-full p-1"
/>
</div>
</div>
<CardContent className="p-4">
<h3 className="font-semibold truncate">{album.name}</h3>