Refactor code structure for improved readability and maintainability

This commit is contained in:
2025-07-02 23:06:49 +00:00
committed by GitHub
parent 62fc5509b0
commit b668c1b6fb
5 changed files with 47 additions and 42 deletions

View File

@@ -1 +1 @@
NEXT_PUBLIC_COMMIT_SHA=a854604 NEXT_PUBLIC_COMMIT_SHA=62fc550

View File

@@ -1,50 +1,58 @@
![splash](https://github.com/sillyangel/mice/blob/main/4xnored.png?raw=true) <p align="left" style="display: flex; align-items: center; gap: 12px;">
# mice (project still reworked) <img src="https://github.com/sillyangel/mice/blob/main/public/icon-512.png?raw=true" alt="Mice Logo" width="64" style="border-radius: 12px;" />
> project still, now with navidrome <strong style="font-size: 2em;">Mice | Navidrome Client</strong>
</p>
> project based on [shadcn/ui](https://github.com/shadcn-ui/ui)'s music template #
This is a modern music streaming web application built with [Next.js](https://nextjs.org/) and [shadcn/ui](https://ui.shadcn.com/), now powered by **Navidrome** for a complete self-hosted music streaming experience. > Project based on [shadcn/ui](https://github.com/shadcn-ui/ui)'s music template.
**✨ New**: Migrated from Firebase + static data to **Navidrome/Subsonic** integration for real music streaming! <!-- This is a music streaming web application built with [Next.js](https://nextjs.org/) and [shadcn/ui](https://ui.shadcn.com/), now powered by **Navidrome** for a complete self-hosted music streaming experience. -->
### Features This is a "Modern" Navidrome (or Subsonic) client built with [Next.js](https://nextjs.org/) and [shadcn/ui](https://ui.shadcn.com/). It creates a beautiful, responsive music streaming web application that connects to your Navidrome server, and fully able to self-host.
- 🎵 **Real Music Streaming** via Navidrome/Subsonic API ## Features
- 📱 **Modern UI** with shadcn/ui components
- 🎨 **Dynamic Album Artwork** from your music library - **Real Music Streaming** via Navidrome/Subsonic API
- **Favorites** - Star albums, artists, and songs - **Modern UI** with shadcn/ui components
- 📋 **Playlist Management** - Create and manage playlists - **Dynamic Album Artwork** from your music library
- 🔍 **Search** - Find music across your entire library - **Favorites** - Star albums, artists, and songs
- 🎧 **Audio Player** with queue management - **Search** - Find music across your entire library
- 📊 **Scrobbling** - Track your listening history - **Audio Player** with queue management
- **Scrobbling** - Track your listening history
<!-- - **Playlist Management** - Create and manage playlists -->
### Preview ### Preview
![preview](https://github.com/sillyangel/mice/blob/main/public/screen.png?raw=true) ![preview](https://github.com/sillyangel/mice/blob/main/public/home-preview.png?raw=true)
## Quick Start ## Quick Start
### Prerequisites ### Prerequisites
- [Navidrome](https://www.navidrome.org/) server running - [Navidrome](https://www.navidrome.org/) server running
- Node.js 18+ and pnpm - Node.js 18+
### Setup ### Setup
1. **Clone and install** 1. **Clone and install the required dependencies**
```bash ```bash
git clone https://github.com/sillyangel/project-still.git git clone https://github.com/sillyangel/project-still.git
cd project-still/ cd project-still/
pnpm install pnpm install
# or npm
npm install
``` ```
2. **Configure Navidrome connection** ## 2. **Configure the Navidrome connection**
First, copy the example environment file:
```bash ```bash
cp .env.example .env cp .env.example .env
``` ```
Edit `.env` with your Navidrome server details: Next, open the new `.env` file and update it with your Navidrome server credentials:
```env ```env
NEXT_PUBLIC_NAVIDROME_URL=http://localhost:4533 NEXT_PUBLIC_NAVIDROME_URL=http://localhost:4533
@@ -54,10 +62,23 @@ NEXT_PUBLIC_POSTHOG_KEY=phc_XXXXXXXXXXXXXXXXXX
NEXT_PUBLIC_POSTHOG_HOST=https://us.i.posthog.com NEXT_PUBLIC_POSTHOG_HOST=https://us.i.posthog.com
``` ```
> **Tip:** If you dont have your own Navidrome server yet, you can use the public demo credentials:
```env
NEXT_PUBLIC_NAVIDROME_URL=https://demo.navidrome.org
NEXT_PUBLIC_NAVIDROME_USERNAME=demo
NEXT_PUBLIC_NAVIDROME_PASSWORD=demo
```
3. **Run the development server** 3. **Run the development server**
```bash ```bash
pnpm dev pnpm dev
# or npm
npm run dev
``` ```
Open [http://localhost:40625](http://localhost:40625) in your browser. Open [http://localhost:40625](http://localhost:40625) in your browser.
@@ -98,10 +119,6 @@ docker run -p 3000:3000 \
📖 **For detailed Docker configuration, environment variables, troubleshooting, and advanced setups, see [DOCKER.md](./DOCKER.md)** 📖 **For detailed Docker configuration, environment variables, troubleshooting, and advanced setups, see [DOCKER.md](./DOCKER.md)**
## Migration from Firebase
This project was migrated from Firebase to Navidrome. See [NAVIDROME_MIGRATION.md](./NAVIDROME_MIGRATION.md) for detailed migration notes and troubleshooting.
## Tech Stack ## Tech Stack
- **Frontend**: Next.js 15, React 19, TypeScript - **Frontend**: Next.js 15, React 19, TypeScript
@@ -110,14 +127,6 @@ This project was migrated from Firebase to Navidrome. See [NAVIDROME_MIGRATION.m
- **Audio**: Web Audio API with streaming - **Audio**: Web Audio API with streaming
- **State**: React Context for global state management - **State**: React Context for global state management
## Contributing
1. Fork the repository
2. Create a feature branch
3. Make your changes
4. Test with your Navidrome server
5. Submit a pull request
## License ## License
This project is licensed under the MIT License. This project is licensed under the MIT License.

View File

@@ -321,11 +321,7 @@ export const FullScreenPlayer: React.FC<FullScreenPlayerProps> = ({ isOpen, onCl
{/* Main Content */} {/* Main Content */}
<div className="flex-1 flex flex-col lg:flex-row gap-4 lg:gap-8 p-4 lg:p-6 pt-0 overflow-hidden min-h-0"> <div className="flex-1 flex flex-col lg:flex-row gap-4 lg:gap-8 p-4 lg:p-6 pt-0 overflow-hidden min-h-0">
{/* Left Side - Album Art and Controls */} {/* Left Side - Album Art and Controls */}
<div className={`flex flex-col items-center min-h-0 flex-1 min-w-0 ${ <div className="flex flex-col items-center justify-center min-h-0 flex-1 min-w-0">
showLyrics && lyrics.length > 0
? 'justify-center lg:justify-start'
: 'justify-center'
}`}>
{/* Album Art */} {/* Album Art */}
<div className="relative mb-4 lg:mb-6 flex-shrink-0"> <div className="relative mb-4 lg:mb-6 flex-shrink-0">
<Image <Image
@@ -457,15 +453,15 @@ export const FullScreenPlayer: React.FC<FullScreenPlayerProps> = ({ isOpen, onCl
<div className="flex-1 min-w-0 min-h-0 flex flex-col" ref={lyricsRef}> <div className="flex-1 min-w-0 min-h-0 flex flex-col" ref={lyricsRef}>
<div className="h-full flex flex-col"> <div className="h-full flex flex-col">
<ScrollArea className="flex-1 min-h-0"> <ScrollArea className="flex-1 min-h-0">
<div className="space-y-3 sm:space-y-4 pr-4 px-2 py-4"> <div className="space-y-3 sm:space-y-4 pl-12 pr-4 py-4">
{lyrics.map((line, index) => ( {lyrics.map((line, index) => (
<div <div
key={index} key={index}
data-lyric-index={index} data-lyric-index={index}
onClick={() => handleLyricClick(line.time)} onClick={() => handleLyricClick(line.time)}
className={`text-sm sm:text-base lg:text-base leading-relaxed transition-all duration-300 break-words cursor-pointer hover:text-foreground hover:scale-102 ${ className={`text-sm sm:text-base lg:text-base leading-relaxed transition-all duration-300 break-words cursor-pointer hover:text-foreground ${
index === currentLyricIndex index === currentLyricIndex
? 'text-foreground font-semibold text-base sm:text-lg lg:text-xl scale-105' ? 'text-foreground font-bold text-lg sm:text-xl lg:text-2xl'
: index < currentLyricIndex : index < currentLyricIndex
? 'text-foreground/60' ? 'text-foreground/60'
: 'text-foreground/40' : 'text-foreground/40'
@@ -475,7 +471,7 @@ export const FullScreenPlayer: React.FC<FullScreenPlayerProps> = ({ isOpen, onCl
overflowWrap: 'break-word', overflowWrap: 'break-word',
hyphens: 'auto', hyphens: 'auto',
paddingBottom: '6px', paddingBottom: '6px',
paddingLeft: '8px' paddingLeft: '16px'
}} }}
title={`Click to jump to ${formatTime(line.time)}`} title={`Click to jump to ${formatTime(line.time)}`}
> >

BIN
public/home-preview.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 370 KiB