Remove Android submodule and update to mobile-only structure

This commit is contained in:
Tomas Dvorak
2026-03-18 20:02:53 +01:00
parent 5152d9dfeb
commit 72358288cd
4 changed files with 564 additions and 181 deletions
-3
View File
@@ -14,6 +14,3 @@
path = swingmusic_mobile path = swingmusic_mobile
url = https://github.com/Dvorinka/swingmusic-mobile.git url = https://github.com/Dvorinka/swingmusic-mobile.git
branch = master branch = master
[submodule "swingmusic_mobile"]
path = swingmusic_mobile
url = https://github.com/Dvorinka/swingmusic-mobile.git
+16
View File
@@ -0,0 +1,16 @@
[submodule "swingmusic-android"]
path = swingmusic-android
url = https://github.com/Dvorinka/swingmusic-extended-android
branch = master
[submodule "swingmusic-desktop"]
path = swingmusic-desktop
url = https://github.com/Dvorinka/swingmusic-extended-desktop
branch = master
[submodule "swingmusic-webclient"]
path = swingmusic-webclient
url = https://github.com/Dvorinka/swingmusic-extended-webclient
branch = master
[submodule "swingmusic-mobile"]
path = swingmusic_mobile
url = https://github.com/Dvorinka/swingmusic-mobile.git
branch = master
+355
View File
@@ -0,0 +1,355 @@
# 🎵 SwingMusic Mobile Development Plan
## 📱 Current Status
### ✅ Completed
- **Desktop App**: Cross-platform (Linux, Windows, macOS) - Tauri + Rust
- **Android App**: Native Kotlin implementation
- **Backend**: Python REST API server
- **Web Client**: Vue.js frontend
- **CI/CD**: Unified release system with semantic versioning
- **Fully convert the current android app app to the unified flutter app - but keep the original folder as a reference and backup dont remove it or edit anything in it, only create in the new one**
### 🎯 Target
- **iOS App**: Flutter cross-platform implementation
- **Unified Mobile**: Single codebase for iOS + Android
## 🚀 Flutter Implementation Plan
### Phase 1: Project Setup & Foundation (Week 1-2)
#### 📁 Repository Structure
```
swingmusic-mobile/
├── lib/
│ ├── core/
│ │ ├── constants/
│ │ ├── themes/
│ │ ├── utils/
│ │ └── widgets/
│ ├── data/
│ │ ├── models/
│ │ ├── repositories/
│ │ └── services/
│ ├── features/
│ │ ├── auth/
│ │ ├── library/
│ │ ├── player/
│ │ ├── search/
│ │ ├── playlists/
│ │ ├── offline/
│ │ └── analytics/
│ └── shared/
│ ├── providers/
│ └── routes/
├── assets/
│ ├── images/
│ ├── fonts/
│ └── audio/
├── test/
├── integration_test/
└── ios/
└── android/
```
#### 🔧 Technical Setup
- [ ] Create `swingmusic-mobile` Flutter submodule
- [ ] Set up project dependencies
- [ ] Configure state management (Provider/Bloc)
- [ ] Set up navigation (go_router)
- [ ] Implement theming system (Material Design 3)
- [ ] Set up API client integration
- [ ] Configure audio services (just_audio)
#### 📦 Core Dependencies
```yaml
dependencies:
flutter:
sdk: flutter
# State Management
provider: ^6.1.1
# or bloc: ^8.1.3
# Navigation
go_router: ^12.1.3
# Audio
just_audio: ^0.9.36
audio_session: ^0.1.16
# UI & Animations
flutter_staggered_animations: ^1.1.1
lottie: ^2.7.0
# Network & API
dio: ^5.3.2
retrofit: ^4.0.3
# Local Storage
hive: ^2.2.3
hive_flutter: ^1.1.0
path_provider: ^2.1.1
# Media & Metadata
audio_metadata: ^4.2.0
# Visualizations
flutter_audio_waveforms: ^1.2.0
# Permissions
permission_handler: ^11.0.1
# Background Processing
workmanager: ^0.5.2
```
### Phase 2: Core Features (Week 3-4)
#### 🎵 Audio Engine
- [ ] Implement audio playback service
- [ ] Background playback support
- [ ] Audio focus management
- [ ] Media session integration
- [ ] Equalizer support
#### 📚 Library Management
- [ ] API integration for music library
- [ ] Local caching with Hive
- [ ] Lazy loading for large libraries
- [ ] Search functionality
- [ ] Metadata extraction
#### 🎨 Core UI Components
- [ ] Material Design 3 theme system
- [ ] Custom audio player widget
- [ ] Track list components
- [ ] Album/artist cards
- [ ] Search interface
### Phase 3: Advanced Features (Week 5-6)
#### 🌊 Visualizations & UI
- [ ] Waveform visualization
- [ ] Audio spectrum analyzer
- [ ] Smooth animations
- [ ] Gesture controls
- [ ] Responsive layouts
#### 💾 Offline Mode
- [ ] Download management
- [ ] Local storage optimization
- [ ] Offline playback
- [ ] Sync with server
- [ ] Storage management
#### 🎤 Lyrics & Metadata
- [ ] Real-time lyrics sync
- [ ] Lyrics display UI
- [ ] Album artwork handling
- [ ] Metadata editing
- [ ] Tag reading
### Phase 4: Enhanced Features (Week 7-8)
#### 📊 Analytics & Insights
- [ ] Listening statistics
- [ ] Play history tracking
- [ ] Favorite tracks/artists
- [ ] Usage analytics dashboard
- [ ] Year-end recap
#### 🎯 User Experience
- [ ] Home screen widgets
- [ ] Notification controls
- [ ] Lock screen integration
- [ ] Car mode support
- [ ] Accessibility features
#### 🔗 Integration
- [ ] Backend API integration
- [ ] Authentication system
- [ ] Playlist synchronization
- [ ] Social features
- [ ] Sharing capabilities
### Phase 5: Testing & Polish (Week 9-10)
#### 🧪 Quality Assurance
- [ ] Unit tests (90%+ coverage)
- [ ] Integration tests
- [ ] Widget tests
- [ ] Performance testing
- [ ] Memory leak testing
#### 🐛 Bug Fixes & Optimization
- [ ] Performance optimization
- [ ] Battery usage optimization
- [ ] Memory management
- [ ] Error handling
- [ ] Edge case coverage
#### 📱 Platform-Specific Features
- [ ] iOS-specific optimizations
- [ ] Android-specific features
- [ ] Platform integration
- [ ] App store preparation
- [ ] Signing and distribution
## 🔧 Technical Architecture
### 🏗️ State Management
**Provider Pattern** (Recommended for simplicity)
```dart
// Audio provider for global state
class AudioProvider extends ChangeNotifier {
AudioPlayer _player;
TrackModel? _currentTrack;
bool _isPlaying = false;
// Audio controls, state management
}
// Library provider for data
class LibraryProvider extends ChangeNotifier {
List<TrackModel> _tracks;
List<AlbumModel> _albums;
List<ArtistModel> _artists;
// Library management
}
```
### 🌐 API Integration
```dart
// Retrofit for type-safe API
@RestApi(baseUrl: 'https://your-api.com')
abstract class MusicApiService {
@GET('/tracks')
Future<List<TrackModel>> getTracks();
@GET('/albums')
Future<List<AlbumModel>> getAlbums();
@POST('/playlists')
Future<PlaylistModel> createPlaylist(@Body() PlaylistModel playlist);
}
```
### 💾 Local Storage
```dart
// Hive for local caching
class TrackAdapter extends TypeAdapter<TrackModel> {
@override
TrackModel read(BinaryReader reader) {
// Deserialization
}
@override
void write(BinaryWriter writer, TrackModel obj) {
// Serialization
}
}
```
## 📋 CI/CD Integration
### 🔄 Build Pipeline Updates
```yaml
# Add to unified-release.yml
build-flutter-mobile:
name: Build Flutter Mobile Apps
runs-on: ubuntu-latest
needs: get-version
if: contains(github.event.inputs.components, 'mobile') || github.event_name == 'push'
strategy:
matrix:
include:
- platform: 'android-arm64'
os: ubuntu-latest
target: 'android-arm64'
- platform: 'android-x64'
os: ubuntu-latest
target: 'android-x64'
- platform: 'ios-arm64'
os: macos-latest
target: 'ios-arm64'
- platform: 'ios-x64'
os: macos-latest
target: 'ios-x64'
```
### 📦 Distribution
- **Android**: APK + AAB for Google Play
- **iOS**: IPA for App Store
- **Testing**: Firebase App Distribution
- **Beta**: TestFlight for iOS
## 🎯 Success Metrics
### 📈 Technical Goals
- [ ] 60 FPS smooth animations
- [ ] < 100ms audio response time
- [ ] < 50MB app size
- [ ] 4+ hour battery life for continuous playback
- [ ] 10,000+ track library support
### 🎨 User Experience Goals
- [ ] < 3 seconds app startup time
- [ ] Intuitive navigation (≤ 3 taps to any feature)
- [ ] Beautiful Material Design 3 interface
- [ ] Accessibility compliance (WCAG 2.1 AA)
- [ ] Multi-language support
### 🔧 Development Goals
- [ ] 90%+ test coverage
- [ ] < 1 week release cycle
- [ ] Zero critical bugs in production
- [ ] Consistent code quality (A+ grade)
- [ ] Comprehensive documentation
## 🚀 Migration Strategy
### 📱 Transition Plan
1. **Parallel Development**: Flutter alongside Android native
2. **Feature Parity**: Match all Android features
3. **Beta Testing**: Internal testing with Flutter app
4. **Public Beta**: Release Flutter version for testing
5. **Phase-out**: Deprecate Android native app
6. **Full Migration**: Complete switch to Flutter
### 🔄 Data Migration
- User preferences and settings
- Offline downloaded content
- Playlists and favorites
- Listening history and statistics
## 📅 Timeline
| Phase | Duration | Key Deliverables |
|-------|----------|------------------|
| Phase 1 | 2 weeks | Project setup, foundation |
| Phase 2 | 2 weeks | Core features, basic app |
| Phase 3 | 2 weeks | Advanced features |
| Phase 4 | 2 weeks | Enhanced features |
| Phase 5 | 2 weeks | Testing, polish |
| **Total** | **10 weeks** | **Production-ready Flutter app** |
## 🎯 Next Steps
### Immediate Actions
1. **Review and approve** this plan
2. **Create Flutter submodule** structure
3. **Set up development environment**
4. **Begin Phase 1 implementation**
### Long-term Vision
- **Unified mobile experience** across iOS and Android
- **Seamless integration** with existing SwingMusic ecosystem
- **Modern, performant** mobile application
- **Cross-platform consistency** with desktop and web
---
*This plan provides a comprehensive roadmap for developing a high-quality Flutter mobile application that integrates seamlessly with the existing SwingMusic ecosystem while delivering an exceptional user experience on both iOS and Android platforms.*
+193 -178
View File
@@ -1,11 +1,11 @@
<div align="center" style="display: flex; justify-content: center; align-items: center;"> <div align="center" style="display: flex; justify-content: center; align-items: center;">
<img class="lo" src='https://github.com/swingmx/swingmusic/raw/master/.github/images/logo-fill.light.svg' style="height: 4rem"> <img class="lo" src='https://github.com/swingmx/swingmusic/raw/master/.github/images/logo-fill.light.svg' style="height: 4rem">
</div> </div>
<div align="center" style="font-size: 2rem"><b>Swing Music</b></div> <div align="center" style="font-size: 2rem"><b>SwingMusic Extended</b></div>
<div align="center"><b><sub><code>v2.1.0</code></sub></b></div> <div align="center"><b><sub><code>v2.1.4</code></sub></b></div>
**<div align="center" style="padding-top: 1.25rem">[Download](https://swingmx.com/downloads) • [Get Android Client](https://github.com/swingmx/android) • <a href="https://github.com/sponsors/swingmx" target="_blank">Sponsor Us ❤️</a> • [Docs](https://swingmx.com/guide/introduction.html) • [Screenshots](https://swingmx.com) • [r/SwingMusicApp](https://www.reddit.com/r/SwingMusicApp)</div>** **<div align="center" style="padding-top: 1.25rem">[Web Client](https://github.com/Dvorinka/swingmusic-extended-webclient) • [Desktop App](https://github.com/Dvorinka/swingmusic-extended-desktop) • [Android App](https://github.com/Dvorinka/swingmusic-extended-android) • [Mobile App](https://github.com/Dvorinka/swingmusic-mobile) • <a href="https://github.com/sponsors/Dvorinka" target="_blank">Sponsor Us ❤️</a></div>**
## ##
@@ -13,108 +13,153 @@
## ##
Swing Music is a fast and beautiful, self-hosted music player for your local audio files. Like a cooler Spotify ... but bring your own music. Just run the app and enjoy your music library in a web browser. SwingMusic Extended is a comprehensive, multi-platform music player ecosystem for your local audio files. Like a cooler Spotify ... but bring your own music. This monorepo contains the backend server and orchestrates all client applications.
## Features ## 🚀 Platform Overview
- **Daily Mixes** - curated everyday based on your listening activity ### 🌐 **Web Client** - [swingmusic-extended-webclient](https://github.com/Dvorinka/swingmusic-extended-webclient)
- **Metadata normalization** - a clean and consistent library - **Status**: ✅ Fully Implemented
- **Album versioning** - normalized albums and association with version labels (eg. Deluxe, Remaster, etc) - **Technology**: Vue 3, TypeScript, Vite, Tailwind CSS
- **Related artist and albums** - **Features**: Progressive Web App, Spotify integration, universal downloader, audio quality controls
- **Folder view** - Browse your music library by folders - **Installation**: `yarn install && yarn dev`
- **Playlist management**
- **Beautiful browser based UI**
- **Silence detection** - Combine cross-fade with silence detection to create a seamless listening experience
- **Collections** - Group albums and artists based on your preferences
- **Statistics** - Get insights into your listening activity
- **Lyrics view**
- **Android client**
- **Last.fm scrobbling**
- **Multi-user support**
- **Cross-platform** - Windows, Linux, MacOS (coming soon), arm64, x86
- **Blazingly fast**
- **Pure awesomeness**
### Installation ### 🖥️ **Desktop App** - [swingmusic-extended-desktop](https://github.com/Dvorinka/swingmusic-extended-desktop)
- **Status**: ✅ Fully Implemented
- **Technology**: Tauri, Rust, Vue.js
- **Features**: Native performance, system tray integration, global hotkeys, file associations
- **Installation**: `npm install && npm run dev`
Swing Music is available as pre-compiled binaries for Windows and Linux. Just download the latest release from the [downloads page](https://swingmusic.vercel.app/downloads) and launch it. ### 📱 **Android App** - [swingmusic-extended-android](https://github.com/Dvorinka/swingmusic-extended-android)
- **Status**: ✅ Fully Implemented
- **Technology**: Kotlin, Jetpack Compose, Android SDK
- **Features**: Material Design 3, offline mode, analytics, background playback
- **Installation**: `./gradlew assembleDebug`
[FFmpeg](https://ffmpeg.org/) is needed for the audio silence skip feature, so you need to install it first. On windows, you can follows [this tutorial](https://phoenixnap.com/kb/ffmpeg-windows) to install FFmpeg. ### 📲 **Flutter Mobile App** - [swingmusic-mobile](https://github.com/Dvorinka/swingmusic-mobile)
- **Status**: 🔄 In Development
- **Technology**: Flutter, Dart
- **Features**: Cross-platform mobile (iOS/Android), unified UI with web client
- **Installation**: `flutter pub get && flutter run`
On Linux, you can install FFmpeg using: ## 🎯 Core Features
```sh ### Backend Server (This Repository)
sudo apt-get install ffmpeg libev-dev libavcodec-extra -y - **Multi-Platform Support** - Serves all client applications
- **Advanced Audio Processing** - Cross-fade, silence detection, gapless playback
- **Metadata Management** - Automatic normalization and organization
- **Multi-User Support** - Individual user profiles and preferences
- **API Integration** - RESTful API with WebSocket support
- **Real-Time Sync** - Synchronizes across all platforms
### Universal Features Across All Platforms
- **Daily Mixes** - Curated playlists based on listening activity
- **Advanced Search** - Full-text search with filters and suggestions
- **Playlist Management** - Create, edit, and organize playlists
- **Folder View** - Browse music by directory structure
- **Statistics & Analytics** - Comprehensive listening insights
- **Lyrics Display** - Real-time lyrics synchronization
- **Last.fm Integration** - Automatic scrobbling
- **Theme Support** - Light/dark modes with system awareness
## 🏗️ Project Structure
```
SwingMusic Extended/
├── src/ # Backend server (Python/FastAPI)
├── swingmusic-webclient/ # Vue.js web application
├── swingmusic-desktop/ # Tauri desktop application
├── swingmusic-android/ # Android native application
├── swingmusic_mobile/ # Flutter cross-platform mobile
├── services/ # Additional services and scripts
└── docs/ # Documentation
``` ```
The `libev` package is needed on Linux and MacOS. You can install it on other system as shown: ## 🚀 Quick Start
```sh ### Prerequisites
# Arch Linux - **Python** 3.11+ for backend
pacman -S libev - **Node.js** 19+ for web client development
- **Flutter** 3.0+ for mobile app
- **Android Studio** for Android development
- **Rust** 1.70+ for desktop development
# Fedora, CentOS ### Backend Installation
dnf install libev-devel
# MacOS
brew install libev
```
Then make the file executable first.
1. **Clone this repository**:
```bash ```bash
chmod a+x ./swingmusic git clone https://github.com/Dvorinka/swingmusic-extended.git
cd swingmusic-extended
./swingmusic
``` ```
The app should start at <http://localhost:1970> by default. Open it in your browser to configure and use Swing Music. You can change the default port by using the `--port` flag. 2. **Install dependencies**:
```bash
# Using uv (recommended)
uv sync
```sh # Or using pip
./swingmusic --port 1980 pip install -r requirements.txt
``` ```
> [!IMPORTANT] 3. **Install system dependencies**:
> The default password for user `admin` is "admin". Please change the password via the settings after first login.
To stream your music from your Android device, you can download the [Android mobile client](https://github.com/swingmx/android). **FFmpeg** (required for audio processing):
```bash
# Ubuntu/Debian
sudo apt-get install ffmpeg libev-dev libavcodec-extra -y
### Options # macOS
brew install ffmpeg libev
Options flags can be passed when starting the app in the terminal to tweak runtime settings or perform tasks. You can use the `-h` flag to see all supported options. # Windows
# Download from https://ffmpeg.org/
> [!TIP]
> You can read more about options in [the docs](https://swingmusic.vercel.app/guide/getting-started.html#options).
### Docker
Pull the latest Docker image and run it:
```sh
docker pull ghcr.io/swingmx/swingmusic:latest
``` ```
```sh 4. **Run the server**:
docker run --name swingmusic -p 1970:1970 \ ```bash
-v /path/to/music:/music \ uv run python run.py
-v /path/to/config:/config \
--restart unless-stopped \
ghcr.io/swingmx/swingmusic:latest
``` ```
Don't forget to replace `/path/to/music` and `/path/to/config` with the appropriate values. In addition, specify the the `/music` directory as the root directory. Using the `Home Directory` option won't work. The server will start at `http://localhost:1970` by default.
> [!TIP] ### Client Applications
> For more info, see the [Docker section](https://swingmusic.vercel.app/guide/getting-started.html#docker) on the docs.
#### Using Docker Compose Each client application has its own repository with detailed setup instructions:
Here's a sample Docker compose file: - **Web Client**: See [swingmusic-extended-webclient](https://github.com/Dvorinka/swingmusic-extended-webclient)
- **Desktop App**: See [swingmusic-extended-desktop](https://github.com/Dvorinka/swingmusic-extended-desktop)
- **Android App**: See [swingmusic-extended-android](https://github.com/Dvorinka/swingmusic-extended-android)
- **Flutter Mobile**: See [swingmusic-mobile](https://github.com/Dvorinka/swingmusic-mobile)
## 🔧 Configuration
### Server Options
```bash
# Change port
uv run python run.py --port 1980
# Enable debug mode
uv run python run.py --debug
# Set music directory
uv run python run.py --music-dir /path/to/music
# All options
uv run python run.py --help
```
### Environment Variables
- `SWINGMUSIC_PORT` - Server port (default: 1970)
- `SWINGMUSIC_MUSIC_DIR` - Music library path
- `SWINGMUSIC_CONFIG_DIR` - Configuration directory
- `SWINGMUSIC_LOG_LEVEL` - Logging level
## 🐳 Docker Deployment
### Using Docker Compose
```yaml ```yaml
services: services:
swingmusic: swingmusic:
image: ghcr.io/swingmx/swingmusic:latest image: ghcr.io/Dvorinka/swingmusic-extended:latest
container_name: swingmusic container_name: swingmusic
volumes: volumes:
- /path/to/music:/music - /path/to/music:/music
@@ -122,124 +167,94 @@ services:
ports: ports:
- "1970:1970" - "1970:1970"
restart: unless-stopped restart: unless-stopped
environment:
- SWINGMUSIC_PORT=1970
``` ```
### Contributing and Development ### Manual Docker
```bash
docker pull ghcr.io/Dvorinka/swingmusic-extended:latest
Swing Music is looking for contributors. If you're interested, please join us at the [Swing Music Community](https://t.me/+9n61PFcgKhozZDE0) group on Telegram. For more information, take a look at https://github.com/swing-opensource/swingmusic/issues/186. docker run --name swingmusic -p 1970:1970 \
-v /path/to/music:/music \
[**CONTRIBUTING GUIDELINES**](.github/contributing.md). -v /path/to/config:/config \
--restart unless-stopped \
> [!TIP] ghcr.io/Dvorinka/swingmusic-extended:latest
> This project runs on Python 3.11 or newer and uses [uv](https://docs.astral.sh/uv) to manage dependencies. Please [install uv](https://docs.astral.sh/uv/getting-started/installation/) before continuing for an easy setup.
To set up this project on your computer follow the following steps:
```sh
# 1. Fork the project
git clone https://github.com/swingmx/swingmusic.git
# or via SSH
git clone git@github.com:swingmx/swingmusic.git
``` ```
```sh ## 🛠️ Development
# 2. Install dependencies
uv sync ### Backend Development
```bash
# Install development dependencies
uv sync --dev
# Run with hot reload
uv run python run.py --reload
# Run tests
uv run pytest
# Run with coverage
uv run pytest --cov=src
``` ```
> [!TIP] ### Updating Submodules
> The `libev` package is needed on Linux and MacOS. You can install it on other system as shown: ```bash
> # Update all submodules
> ```sh git submodule update --remote --merge
> # Arch Linux
> pacman -S libev
>
> # Fedora, CentOS
> dnf install libev-devel
>
> # MacOS
> brew install libev
> ```
```sh # Update specific submodule
# 4. Run the program git submodule update --remote swingmusic-webclient
uv run python run.py # Initialize after cloning
git submodule update --init --recursive
``` ```
### License ## 📊 Platform Implementation Status
This software is provided to you with terms stated in the [AGPLv3 License](https://github.com/swingmx/swingmusic/blob/master/LICENSE) or any later version. Read the full text in the `LICENSE` file located at the root of this repository. | Platform | Status | Features | Last Updated |
|----------|--------|----------|-------------|
| **Backend** | ✅ Complete | Full API, multi-user, real-time sync | Active |
| **Web Client** | ✅ Complete | PWA, Spotify integration, downloader | Active |
| **Desktop App** | ✅ Complete | Native performance, system integration | Active |
| **Android App** | ✅ Complete | Material Design 3, offline mode | Active |
| **Flutter Mobile** | 🔄 In Development | Cross-platform iOS/Android | In Progress |
### Contributors ## 🤝 Contributing
Shout out to the following code contributors who have helped maintain and improve Swing Music: We welcome contributions! Please see our [Contributing Guidelines](.github/CONTRIBUTING.md) for details.
<div align="left"> ### Development Workflow
<table> 1. Fork this repository
<tr> 2. Create a feature branch
<td align="center"> 3. Make your changes
<a href="https://github.com/cwilvx"> 4. Test across all platforms
<img src="https://github.com/cwilvx.png" width="80px;"/> 5. Submit a pull request
<br />
<sub><b>@cwilvx</b></sub> ### Platform-Specific Contributions
</a> - **Backend**: Submit PRs to this repository
</td> - **Web Client**: Submit PRs to [swingmusic-extended-webclient](https://github.com/Dvorinka/swingmusic-extended-webclient)
<td align="center"> - **Desktop App**: Submit PRs to [swingmusic-extended-desktop](https://github.com/Dvorinka/swingmusic-extended-desktop)
<a href="https://github.com/Ericgacoki"> - **Android App**: Submit PRs to [swingmusic-extended-android](https://github.com/Dvorinka/swingmusic-extended-android)
<img src="https://github.com/Ericgacoki.png" width="80px;" alt=""/> - **Flutter Mobile**: Submit PRs to [swingmusic-mobile](https://github.com/Dvorinka/swingmusic-mobile)
<br />
<sub><b>@Ericgacoki</b></sub> ## 📄 License
</a>
</td> This project is licensed under the AGPL-3.0 License - see the [LICENSE](LICENSE) file for details.
<td align="center">
<a href="https://github.com/Simonh2o"> ## 🔗 Links
<img src="https://github.com/Simonh2o.png" width="80px;"/>
<br /> - **Main Repository**: [swingmusic-extended](https://github.com/Dvorinka/swingmusic-extended)
<sub><b>@Simonh2o</b></sub> - **Web Client**: [swingmusic-extended-webclient](https://github.com/Dvorinka/swingmusic-extended-webclient)
</a> - **Desktop App**: [swingmusic-extended-desktop](https://github.com/Dvorinka/swingmusic-extended-desktop)
</td> - **Android App**: [swingmusic-extended-android](https://github.com/Dvorinka/swingmusic-extended-android)
<td align="center"> - **Flutter Mobile**: [swingmusic-mobile](https://github.com/Dvorinka/swingmusic-mobile)
<a href="https://github.com/tcsenpai">
<img src="https://github.com/tcsenpai.png" width="80px;"/> ## 🙏 Acknowledgments
<br />
<sub><b>@tcsenpai</b></sub> Based on the original [SwingMusic](https://github.com/swingmx/swingmusic) by swingmx, extended with additional platforms and features.
</a>
</td> ---
<td align="center">
<a href="https://github.com/jensgrunzer1"> **Built with ❤️ by the SwingMusic Extended community**
<img src="https://github.com/jensgrunzer1.png" width="80px;"/>
<br />
<sub><b>@jensgrunzer1</b></sub>
</a>
</td>
<td align="center">
<a href="https://github.com/Type-Delta">
<img src="https://github.com/Type-Delta.png" width="80px;" alt=""/>
<br />
<sub><b>@Type-Delta</b></sub>
</a>
</td>
<td align="center">
<a href="https://github.com/MarcOrfilaCarreras">
<img src="https://github.com/MarcOrfilaCarreras.png" width="80px;" alt=""/>
<br />
<sub><b>@MarcOrfilaCarreras</b></sub>
</a>
</td>
</tr>
<tr>
<td align="center">
<a href="https://github.com/tralph3">
<img src="https://github.com/tralph3.png" width="80px;" alt=""/>
<br />
<sub><b>@tralph3</b></sub>
</a>
</td>
</tr>
</table>
</div>