Refactor code structure for improved readability and maintainability

This commit is contained in:
2025-06-19 16:11:31 +00:00
committed by GitHub
parent a1a4c47794
commit c954348ad1
13 changed files with 12 additions and 246 deletions

View File

@@ -1,5 +0,0 @@
{
"projects": {
"default": "offbrandspotifydb"
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 72 KiB

View File

@@ -1,151 +0,0 @@
# Navidrome Integration Migration
This project has been migrated from a Firebase-based system with static data to use **Navidrome/Subsonic** as the backend music server.
## What Changed
### Removed:
- Firebase authentication and database
- Static album/artist data files
- Custom database URLs and tracklist JSON files
### Added:
- Navidrome/Subsonic API integration
- Real-time music streaming
- Dynamic music library loading
- Album cover art from Navidrome
- Playlist management through Navidrome
- Star/favorite functionality
- Scrobbling support
## Setup Instructions
### 1. Install Navidrome
First, you need to set up a Navidrome server. You can:
- **Self-host**: Follow the [Navidrome installation guide](https://www.navidrome.org/docs/installation/)
- **Docker**: Use the official Docker image
- **Pre-built binaries**: Download from GitHub releases
### 2. Configure Environment Variables
Copy `.env.example` to `.env.local` and configure your Navidrome server:
```bash
cp .env.example .env.local
```
Edit `.env.local`:
```env
NEXT_PUBLIC_NAVIDROME_URL=http://localhost:4533
NEXT_PUBLIC_NAVIDROME_USERNAME=your_username
NEXT_PUBLIC_NAVIDROME_PASSWORD=your_password
```
For production, use your actual Navidrome server URL:
```env
NEXT_PUBLIC_NAVIDROME_URL=https://your-navidrome-server.com
NEXT_PUBLIC_NAVIDROME_USERNAME=your_username
NEXT_PUBLIC_NAVIDROME_PASSWORD=your_password
```
### 3. Install Dependencies
Remove Firebase dependencies and install:
```bash
pnpm install
```
### 4. Run the Application
```bash
pnpm dev
```
## Features
### Music Library
- **Albums**: Browse all albums in your Navidrome library
- **Artists**: Browse all artists with album counts
- **Songs**: Play individual tracks with streaming
- **Search**: Search across artists, albums, and songs
- **Playlists**: Create and manage playlists
### Audio Player
- **Streaming**: Direct streaming from Navidrome server
- **Queue Management**: Add albums/artists to queue
- **Scrobbling**: Track listening history
- **Controls**: Play, pause, skip, volume control
### User Features
- **Favorites**: Star/unstar albums, artists, and songs
- **Playlists**: Create, edit, and delete playlists
- **Recently Added**: See newest additions to your library
- **Album Artwork**: High quality cover art from Navidrome
## API Integration
The app uses the Subsonic API (compatible with Navidrome) with these endpoints:
- `ping` - Test server connection
- `getArtists` - Get all artists
- `getAlbums` - Get albums (newest, recent, etc.)
- `getAlbum` - Get album details and tracks
- `search3` - Search music library
- `getPlaylists` - Get user playlists
- `stream` - Stream audio files
- `getCoverArt` - Get album/artist artwork
- `star/unstar` - Favorite items
- `scrobble` - Track listening
## File Structure
```
lib/
navidrome.ts # Navidrome API client
app/
components/
NavidromeContext.tsx # React context for Navidrome data
AudioPlayerContext.tsx # Updated for Navidrome streaming
album-artwork.tsx # Updated for Navidrome albums
artist-icon.tsx # Updated for Navidrome artists
AudioPlayer.tsx # Updated for streaming
```
## Migration Notes
- **Authentication**: Removed Firebase auth (Navidrome handles users)
- **Data Source**: Now uses live music library instead of static JSON
- **Streaming**: Direct audio streaming instead of static file URLs
- **Cover Art**: Dynamic cover art from Navidrome instead of static images
- **Playlists**: Managed through Navidrome instead of static data
## Troubleshooting
### Connection Issues
1. Verify Navidrome server is running
2. Check URL, username, and password in `.env.local`
3. Ensure CORS is properly configured in Navidrome
4. Check network connectivity
### Audio Issues
1. Verify audio files are properly imported in Navidrome
2. Check browser audio permissions
3. Ensure audio codecs are supported
### Performance
1. Navidrome server performance affects loading times
2. Consider server location for streaming quality
3. Check network bandwidth for audio streaming
## Development
The app now uses TypeScript interfaces that match the Subsonic API responses. All components have been updated to work with the new data structure and real-time streaming.
Key changes:
- Album interface now includes Navidrome-specific fields
- Artist interface includes album counts and cover art
- Song interface includes streaming URLs and metadata
- Playlist interface matches Navidrome playlist structure

View File

@@ -37,7 +37,7 @@ const Ihateserverside: React.FC<IhateserversideProps> = ({ children }) => {
{/* Main Content Area */}
<div className="flex-1 flex overflow-hidden">
{isSidebarVisible && (
<div className="w-64 flex-shrink-0">
<div className="w-64 flex-shrink-0 border-r">
<Sidebar
playlists={playlists}
className="h-full overflow-y-auto"

View File

@@ -84,7 +84,7 @@ export function Menu({ toggleSidebar, isSidebarVisible, toggleStatusBar, isStatu
<>
<Menubar className="rounded-none border-b border-none px-2 lg:px-4">
<MenubarMenu>
<MenubarTrigger className="font-bold">offbrand spotify</MenubarTrigger>
<MenubarTrigger className="font-bold">mice</MenubarTrigger>
<MenubarContent>
<MenubarItem onClick={() => setOpen(true)}>About Music</MenubarItem>
<MenubarSeparator />

View File

@@ -2,48 +2,6 @@
@tailwind components;
@tailwind utilities;
body {
font-family: Arial, Helvetica, sans-serif;
}
@layer utilities {
.text-balance {
text-wrap: balance;
}
}
@layer base {
:root {
--background: 0 0% 100%;
--foreground: 240 10% 3.9%;
--card: 0 0% 100%;
--card-foreground: 240 10% 3.9%;
--popover: 0 0% 100%;
--popover-foreground: 240 10% 3.9%;
--primary: 221.2 83.2% 53.3%;
--primary-foreground: 0 0% 98%;
--secondary: 240 4.8% 95.9%;
--secondary-foreground: 240 5.9% 10%;
--muted: 240 4.8% 95.9%;
--muted-foreground: 240 3.8% 46.1%;
--accent: 240 4.8% 95.9%;
--accent-foreground: 240 5.9% 10%;
--destructive: 0 84.2% 60.2%;
--destructive-foreground: 0 0% 98%;
--border: 240 5.9% 90%;
--input: 240 5.9% 90%;
--ring: 240 5.9% 10%;
--radius: 0.5rem;
--chart-1: 12 76% 61%;
--chart-2: 173 58% 39%;
--chart-3: 197 37% 24%;
--chart-4: 43 74% 66%;
--chart-5: 27 87% 67%;
}
@tailwind base;
@tailwind components;
@tailwind utilities;
body {
font-family: Arial, Helvetica, sans-serif;
@@ -82,9 +40,9 @@ body {
--chart-4: 280 65% 60%;
--chart-5: 340 75% 55%;
--hover: 240 27% 11%;
--radius: 0.5rem;
}
/* Blue Theme Dark */
.theme-blue.dark {
--background: 240 10% 3.9%;
@@ -107,6 +65,7 @@ body {
--input: 217.2 32.6% 17.5%;
--ring: 224.3 76.3% 48%;
--hover: 240 27% 11%;
--radius: 0.5rem;
}
/* Violet Theme Dark */
@@ -130,36 +89,10 @@ body {
--border: 215 27.9% 16.9%;
--input: 215 27.9% 16.9%;
--ring: 263.4 70% 50.4%;
--radius: 0.5rem;
}
/* Default dark mode (fallback) */
.dark {
--background: 240 10% 3.9%;
--foreground: 0 0% 98%;
--card: 240 10% 3.9%;
--card-foreground: 0 0% 98%;
--popover: 240 10% 3.9%;
--popover-foreground: 0 0% 98%;
--primary: 217.2 91.2% 59.8%;
--primary-foreground: 222.2 47.4% 11.2%;
--secondary: 217.2 32.6% 17.5%;
--secondary-foreground: 0 0% 98%;
--muted: 217.2 32.6% 17.5%;
--muted-foreground: 215 20.2% 65.1%;
--accent: 217.2 32.6% 17.5%;
--accent-foreground: 0 0% 98%;
--destructive: 0 62.8% 30.6%;
--destructive-foreground: 0 0% 98%;
--border: 217.2 32.6% 17.5%;
--input: 217.2 32.6% 17.5%;
--ring: 224.3 76.3% 48%;
--chart-1: 220 70% 50%;
--chart-2: 160 60% 45%;
--chart-3: 30 80% 55%;
--chart-4: 280 65% 60%;
--chart-5: 340 75% 55%;
--hover: 240 27% 11%;
}
}
.dark {
--background: 240 10% 3.9%;
@@ -187,8 +120,9 @@ body {
--chart-4: 280 65% 60%;
--chart-5: 340 75% 55%;
--hover: 240 27% 11%;
--radius: 0.5rem;
}
}

View File

@@ -16,8 +16,8 @@ export const viewport: Viewport = {
export const metadata: Metadata = {
title: {
template: 'offbrand spotify | %s',
default: 'offbrand spotify',
template: 'mice | %s',
default: 'mice',
},
description: 'a very awesome music streaming service',
robots: {

View File

@@ -2,9 +2,9 @@ import type { MetadataRoute } from 'next'
export default function manifest(): MetadataRoute.Manifest {
return {
name: 'Offbrand Spotify',
name: 'mice',
short_name: 'Offbrand',
description: 'a very offbrand spotify clone',
description: 'a very mice clone',
start_url: '/',
categories: ["music", "entertainment"],
display_override: ['window-controls-overlay'],

View File

@@ -1,12 +0,0 @@
border is located at *
hsl(214.3deg 3.81% 25%)
background color in sticky top-0
hsl(0deg 0% 5.86%)
.text muted foreground
hsl(0deg 0% 58.47%)
change in body color
hsl(0 0% 100%)

BIN
image.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 302 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 483 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 370 KiB

Binary file not shown.