🎉 Initial commit: AudiOhm - Alternative à Spotify avec streaming YouTube
Features: - Frontend Flutter avec thème néon cyberpunk - Backend FastAPI avec streaming YouTube - Base de données PostgreSQL + Redis - Authentification JWT complète - Recherche multi-source (DB + YouTube) - Playlists CRUD avec drag & drop - Queue management - Settings avec audio quality - Interface adaptative (Desktop + Mobile) Tech Stack: - Frontend: Flutter 3.2+, Riverpod - Backend: Python 3.11+, FastAPI - Database: PostgreSQL 15+ - Cache: Redis 7+ - Streaming: yt-dlp + FFmpeg 🚀 Generated with Claude Code Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,298 @@
|
||||
# Settings Page Integration Checklist
|
||||
|
||||
## Setup Steps
|
||||
|
||||
### 1. Install Dependencies
|
||||
```bash
|
||||
cd frontend
|
||||
flutter pub get
|
||||
```
|
||||
|
||||
Required dependencies (already added to pubspec.yaml):
|
||||
- ✅ `package_info_plus: ^5.0.1`
|
||||
- ✅ `image_picker: ^1.0.7`
|
||||
- ✅ `shared_preferences: ^2.2.2` (already present)
|
||||
- ✅ `path_provider: ^2.1.2` (already present)
|
||||
|
||||
### 2. Platform Configuration
|
||||
|
||||
#### Android (android/app/src/main/AndroidManifest.xml)
|
||||
Add these permissions inside `<manifest>` tag:
|
||||
|
||||
```xml
|
||||
<!-- For image picker -->
|
||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
|
||||
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" android:minSdkVersion="33"/>
|
||||
|
||||
<!-- For cache management -->
|
||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
|
||||
```
|
||||
|
||||
#### iOS (ios/Runner/Info.plist)
|
||||
Add these keys:
|
||||
|
||||
```xml
|
||||
<key>NSPhotoLibraryUsageDescription</key>
|
||||
<string>We need access to your photo library to let you select a profile picture.</string>
|
||||
<key>NSPhotoLibraryAddUsageDescription</key>
|
||||
<string>We need access to save photos to your library.</string>
|
||||
```
|
||||
|
||||
### 3. Import the Settings Page
|
||||
|
||||
```dart
|
||||
import 'package:spotify_le_2/presentation/pages/settings/settings_page.dart';
|
||||
```
|
||||
|
||||
### 4. Add Navigation Route
|
||||
|
||||
#### Option A: Direct Navigation
|
||||
```dart
|
||||
// In your home page, profile button, etc.
|
||||
onPressed: () {
|
||||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) => const SettingsPage(),
|
||||
),
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
#### Option B: Go Router
|
||||
```dart
|
||||
// In router configuration
|
||||
GoRoute(
|
||||
path: '/settings',
|
||||
builder: (context, state) => const SettingsPage(),
|
||||
),
|
||||
```
|
||||
|
||||
#### Option C: Bottom Navigation
|
||||
```dart
|
||||
NavigationBar(
|
||||
destinations: const [
|
||||
NavigationDestination(icon: Icon(Icons.home), label: 'Home'),
|
||||
NavigationDestination(icon: Icon(Icons.search), label: 'Search'),
|
||||
NavigationDestination(icon: Icon(Icons.settings), label: 'Settings'),
|
||||
],
|
||||
onDestinationSelected: (index) {
|
||||
if (index == 2) { // Settings tab
|
||||
// Navigate to settings or show as current page
|
||||
}
|
||||
},
|
||||
)
|
||||
```
|
||||
|
||||
### 5. Provider Setup (Already Done)
|
||||
|
||||
The `settingsProvider` is already set up in:
|
||||
`frontend/lib/presentation/providers/settings_provider.dart`
|
||||
|
||||
It automatically:
|
||||
- Initializes SharedPreferences
|
||||
- Loads settings on app start
|
||||
- Watches AuthApiService for user data
|
||||
- Persists all settings changes
|
||||
|
||||
### 6. Test the Integration
|
||||
|
||||
#### Manual Testing Checklist
|
||||
|
||||
**Profile Section:**
|
||||
- [ ] Avatar displays correctly (default or from URL)
|
||||
- [ ] Display name and email show
|
||||
- [ ] Premium badge appears for premium users
|
||||
- [ ] Edit Profile button opens dialog
|
||||
- [ ] Display name can be edited
|
||||
- [ ] Image picker opens (requires device/emulator)
|
||||
|
||||
**Audio Quality:**
|
||||
- [ ] All four quality options display
|
||||
- [ ] Selection works correctly
|
||||
- [ ] Premium lock shows for non-premium users
|
||||
- [ ] Settings persist after app restart
|
||||
|
||||
**Playback Settings:**
|
||||
- [ ] Crossfade toggle works
|
||||
- [ ] Duration slider appears when enabled
|
||||
- [ ] Gapless playback toggle works
|
||||
- [ ] Normalize volume toggle works
|
||||
- [ ] All settings persist
|
||||
|
||||
**Downloads:**
|
||||
- [ ] Mobile data toggle works
|
||||
- [ ] Explicit content toggle works
|
||||
- [ ] Settings persist after restart
|
||||
|
||||
**Cache Management:**
|
||||
- [ ] Cache size displays (may show "0 MB" initially)
|
||||
- [ ] Clear cache button works
|
||||
- [ ] Confirmation dialog appears
|
||||
- [ ] Success snackbar shows
|
||||
- [ ] Cache size updates after clearing
|
||||
|
||||
**About Section:**
|
||||
- [ ] App version displays correctly
|
||||
- [ ] Licenses page opens
|
||||
- [ ] License information loads
|
||||
|
||||
**Logout:**
|
||||
- [ ] Logout button works
|
||||
- [ ] Confirmation dialog appears
|
||||
- [ ] User is logged out
|
||||
- [ ] Redirected to login page
|
||||
|
||||
**Error Handling:**
|
||||
- [ ] Network errors display
|
||||
- [ ] Error messages are clear
|
||||
- [ ] Error dismiss button works
|
||||
- [ ] Retry possible
|
||||
|
||||
### 7. Optional Enhancements
|
||||
|
||||
#### Add Settings Icon to App Bar
|
||||
```dart
|
||||
AppBar(
|
||||
title: Text('Home'),
|
||||
actions: [
|
||||
IconButton(
|
||||
icon: Icon(Icons.settings),
|
||||
onPressed: () => Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(builder: (_) => const SettingsPage()),
|
||||
),
|
||||
),
|
||||
],
|
||||
)
|
||||
```
|
||||
|
||||
#### Add Settings to Drawer Menu
|
||||
```dart
|
||||
Drawer(
|
||||
child: ListView(
|
||||
children: [
|
||||
DrawerHeader(...),
|
||||
ListTile(
|
||||
leading: Icon(Icons.settings),
|
||||
title: Text('Settings'),
|
||||
onTap: () {
|
||||
Navigator.pop(context); // Close drawer
|
||||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(builder: (_) => const SettingsPage()),
|
||||
);
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
)
|
||||
```
|
||||
|
||||
#### Add to User Profile Menu
|
||||
```dart
|
||||
PopupMenuButton<String>(
|
||||
onSelected: (value) {
|
||||
if (value == 'settings') {
|
||||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(builder: (_) => const SettingsPage()),
|
||||
);
|
||||
}
|
||||
},
|
||||
itemBuilder: (context) => [
|
||||
PopupMenuItem(value: 'settings', child: Text('Settings')),
|
||||
],
|
||||
)
|
||||
```
|
||||
|
||||
### 8. Verification Commands
|
||||
|
||||
```bash
|
||||
# Check if all files exist
|
||||
ls -la frontend/lib/presentation/providers/settings_provider.dart
|
||||
ls -la frontend/lib/presentation/pages/settings/settings_page.dart
|
||||
ls -la frontend/lib/presentation/widgets/settings/*.dart
|
||||
|
||||
# Verify dependencies
|
||||
flutter pub deps | grep -E "(package_info_plus|image_picker)"
|
||||
|
||||
# Run the app
|
||||
flutter run
|
||||
|
||||
# Build for testing
|
||||
flutter build apk --debug
|
||||
flutter build ios --debug
|
||||
```
|
||||
|
||||
### 9. Common Issues & Solutions
|
||||
|
||||
**Issue: Image picker doesn't open**
|
||||
- Solution: Add permissions to AndroidManifest.xml and Info.plist
|
||||
- Real device required (doesn't work on some emulators)
|
||||
|
||||
**Issue: Cache size shows "Unknown"**
|
||||
- Solution: Normal on first launch or if no cache exists
|
||||
- Cache will accumulate as app is used
|
||||
|
||||
**Issue: Settings don't persist**
|
||||
- Solution: Ensure SharedPreferences is initialized
|
||||
- Check for storage permissions on older Android versions
|
||||
|
||||
**Issue: Premium features not unlocking**
|
||||
- Solution: Ensure backend correctly sets `is_premium` flag
|
||||
- Check user data is loaded from API
|
||||
|
||||
**Issue: Avatar upload doesn't work**
|
||||
- Solution: Server-side upload endpoint required
|
||||
- Current implementation only selects local image
|
||||
- Implement multipart/form-data upload on backend
|
||||
|
||||
### 10. Next Steps
|
||||
|
||||
1. **Backend**: Implement avatar upload endpoint
|
||||
2. **Testing**: Test on real devices (iOS and Android)
|
||||
3. **Polish**: Add loading skeletons during initial load
|
||||
4. **Analytics**: Track settings changes
|
||||
5. **A/B Testing**: Test default settings values
|
||||
6. **Documentation**: Add user-facing help text
|
||||
7. **Localization**: Add translations for all text
|
||||
|
||||
## Support Files Created
|
||||
|
||||
- ✅ `SETTINGS_PAGE_README.md` - Complete implementation guide
|
||||
- ✅ `SETTINGS_PREVIEW.md` - Visual design documentation
|
||||
- ✅ `settings_page_example.dart` - Integration examples
|
||||
- ✅ `INTEGRATION_CHECKLIST.md` - This file
|
||||
|
||||
## Quick Reference
|
||||
|
||||
**Files Created:**
|
||||
- `frontend/lib/presentation/providers/settings_provider.dart`
|
||||
- `frontend/lib/presentation/pages/settings/settings_page.dart`
|
||||
- `frontend/lib/presentation/widgets/settings/settings_tile.dart`
|
||||
- `frontend/lib/presentation/widgets/settings/profile_section.dart`
|
||||
- `frontend/lib/presentation/widgets/settings/audio_quality_selector.dart`
|
||||
- `frontend/lib/presentation/widgets/settings/cache_management_tile.dart`
|
||||
- `frontend/lib/presentation/widgets/settings/edit_profile_dialog.dart`
|
||||
|
||||
**Import Path:**
|
||||
```dart
|
||||
import 'package:spotify_le_2/presentation/pages/settings/settings_page.dart';
|
||||
```
|
||||
|
||||
**Provider Access:**
|
||||
```dart
|
||||
final settingsState = ref.watch(settingsProvider);
|
||||
final settingsNotifier = ref.read(settingsProvider.notifier);
|
||||
```
|
||||
|
||||
**Navigation:**
|
||||
```dart
|
||||
Navigator.push(context, MaterialPageRoute(builder: (_) => const SettingsPage()));
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
**All files created and ready for integration! 🚀**
|
||||
Reference in New Issue
Block a user