a89c7894cf
Backend: - FastAPI avec PostgreSQL et Redis - Authentification JWT complète - API REST pour musique, playlists, recherche - Streaming audio via yt-dlp - SQLAlchemy 2.0 async Frontend: - Flutter avec thème néon cyberpunk - State management Riverpod - Layout adaptatif desktop/mobile - Lecteur audio avec mini-player Infrastructure: - Docker Compose (PostgreSQL + Redis) - Scripts d'installation automatisés - Scripts de build pour exécutables Fichiers ajoutés: - BUILD_CLIENT_*.bat/sh: Scripts de compilation - BUILD_CLIENT_README.md: Documentation compilation - CHECK_FLUTTER.sh: Vérificateur d'environnement - requirements.txt mis à jour pour Python 3.13 - Modèles SQLAlchemy corrigés (metadata -> extra_metadata) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
299 lines
7.6 KiB
Markdown
299 lines
7.6 KiB
Markdown
# 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! 🚀**
|