feat: Modernisation UI/UX et configuration Flutter multi-plateforme
Phase 1 - Corrections Critiques: - Fixed memory leaks dans music_provider.dart (stream subscriptions) - Fixed race conditions dans search_provider.dart (stale results) - Fixed token refresh errors dans api_service.dart - Improved error handling avec messages utilisateur - Changed API URL to HTTPS by default Phase 2 - Améliorations UX Desktop: - Ajouté cursor pointers sur tous les éléments cliquables - Implémenté hover states avec effets néon glow (200ms transitions) - Créé skeleton loading states avec shimmer animation - Ajouté widgets: ClickableWrapper, ErrorDisplay, SkeletonLoading - Enhanced visual feedback pour desktop users Phase 3 - Configuration Flutter: - Configuré Android (Gradle 8.1.0, Kotlin 1.9.0, minSdk 21, targetSdk 34) - Créé launcher icons cyberpunk néon (5 densités) - Configuré Windows desktop (structure complète) - Activé Linux desktop support - Ajouté package équatable pour entités de domaine - Corrigé imports (colors.dart, auth_provider.dart) - Fixed Dio API compatibility (RequestOptions) Documentation: - STYLE_GUIDE.md: Guide complet (100+ pages) - DESIGN_IMPLEMENTATION_GUIDE.md: Implémentation Flutter - BUILD_STATUS.md: Status builds + troubleshooting - QUICKSTART_BUILDS.md: Guide rapide - BUILD_INDEX.md: Index documentation - PHASE_1_CORRECTIONS.md: Corrections Phase 1 - PHASE_2_UX_IMPROVEMENTS.md: Améliorations Phase 2 - PR_REVIEW_SUMMARY.md: Revue code complète - CODE_ANALYSIS_AND_PRIORITIES.md: Analyse code Scripts & Builds: - BUILD_ALL.sh: Script automatisé builds multi-plateforme - builds/: Structure avec README par plateforme - design-system/: Système de design complet Backend: - Ajouté streaming HTTP Range pour audio progressif - Enhanced YouTube service avec métadonnées complètes - Improved error handling et validation Generated with [Claude Code](https://claude.com/claude-code) via [Happy](https://happy.engineering) Co-Authored-By: Claude <noreply@anthropic.com> Co-Authored-By: Happy <yesreply@happy.engineering>
This commit is contained in:
@@ -0,0 +1,410 @@
|
||||
# AudiOhm - Quick Reference Guide
|
||||
|
||||
**Pour les développeurs** - Référence rapide pour les tâches courantes
|
||||
|
||||
---
|
||||
|
||||
## 🎨 Couleurs les Plus Utilisées
|
||||
|
||||
```dart
|
||||
// Imports
|
||||
import '../../core/theme/colors.dart';
|
||||
|
||||
// Backgrounds
|
||||
AppColors.background // #0A0E27 - Fond principal
|
||||
AppColors.surface // #151932 - Cards, panels
|
||||
AppColors.surfaceElevated // #1F2342 - Hover
|
||||
|
||||
// Néon accents
|
||||
AppColors.primary // #00F0FF - Cyan (CTA principal)
|
||||
AppColors.secondary // #BF00FF - Violet (secondaire)
|
||||
AppColors.accent // #FF006E - Rose (likes, highlights)
|
||||
|
||||
// Text
|
||||
AppColors.textPrimary // #F0F4F8 - Titres
|
||||
AppColors.textSecondary // #9BA3B8 - Descriptions
|
||||
AppColors.textTertiary // #6B7280 - Disabled
|
||||
|
||||
// Gradients
|
||||
AppColors.gradientPrimary // Cyan → Violet
|
||||
AppColors.gradientAccent // Violet → Rose
|
||||
AppColors.gradientFull // Cyan → Violet → Rose
|
||||
|
||||
// Glow effects
|
||||
AppColors.glowPrimary // BoxShadow cyan
|
||||
AppColors.glowSecondary // BoxShadow violet
|
||||
AppColors.glowAccent // BoxShadow rose
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📝 Typography
|
||||
|
||||
```dart
|
||||
// Imports
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
|
||||
// Heading - Space Grotesk
|
||||
Text(
|
||||
'Title',
|
||||
style: GoogleFonts.spaceGrotesk(
|
||||
fontSize: 24,
|
||||
fontWeight: FontWeight.w700,
|
||||
color: AppColors.textPrimary,
|
||||
),
|
||||
)
|
||||
|
||||
// Body - Outfit
|
||||
Text(
|
||||
'Body text',
|
||||
style: GoogleFonts.outfit(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w400,
|
||||
color: AppColors.textSecondary,
|
||||
height: 1.6,
|
||||
),
|
||||
)
|
||||
```
|
||||
|
||||
### Sizes Rapides
|
||||
|
||||
```dart
|
||||
display: 48px // Hero
|
||||
h1: 36px // Page title
|
||||
h2: 28px // Section
|
||||
h3: 22px // Card title
|
||||
body: 16px // Standard
|
||||
small: 14px // Secondary
|
||||
caption: 12px // Metadata
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📏 Spacing
|
||||
|
||||
```dart
|
||||
// Multiples de 4px
|
||||
4px // Tight gaps
|
||||
8px // Small gaps
|
||||
12px // Compact padding
|
||||
16px // Standard padding
|
||||
24px // Section padding
|
||||
32px // Large gaps
|
||||
48px // Section separation
|
||||
64px // Hero sections
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Widgets Courants
|
||||
|
||||
### Button avec Glow
|
||||
|
||||
```dart
|
||||
Container(
|
||||
decoration: BoxDecoration(
|
||||
gradient: AppColors.gradientPrimary,
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
boxShadow: AppColors.glowPrimary,
|
||||
),
|
||||
child: ElevatedButton(
|
||||
onPressed: () {},
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: Colors.transparent,
|
||||
shadowColor: Colors.transparent,
|
||||
padding: EdgeInsets.symmetric(horizontal: 24, vertical: 12),
|
||||
),
|
||||
child: Text(
|
||||
'Button',
|
||||
style: TextStyle(
|
||||
color: AppColors.textInverted,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
```
|
||||
|
||||
### Card avec Hover
|
||||
|
||||
```dart
|
||||
class MyCard extends StatefulWidget {
|
||||
@override
|
||||
State<MyCard> createState() => _MyCardState();
|
||||
}
|
||||
|
||||
class _MyCardState extends State<MyCard> {
|
||||
bool _isHovered = false;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return MouseRegion(
|
||||
onEnter: (_) => setState(() => _isHovered = true),
|
||||
onExit: (_) => setState(() => _isHovered = false),
|
||||
cursor: SystemMouseCursors.click,
|
||||
child: GestureDetector(
|
||||
onTap: () => print('Tapped!'),
|
||||
child: AnimatedContainer(
|
||||
duration: Duration(milliseconds: 200),
|
||||
decoration: BoxDecoration(
|
||||
color: AppColors.surface,
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
border: Border.all(
|
||||
color: _isHovered ? AppColors.primary : AppColors.border,
|
||||
width: _isHovered ? 2 : 1,
|
||||
),
|
||||
boxShadow: _isHovered
|
||||
? [
|
||||
BoxShadow(
|
||||
color: AppColors.primary.withOpacity(0.3),
|
||||
blurRadius: 20,
|
||||
),
|
||||
]
|
||||
: null,
|
||||
),
|
||||
child: Padding(
|
||||
padding: EdgeInsets.all(20),
|
||||
child: /* Content */,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Input Field
|
||||
|
||||
```dart
|
||||
TextField(
|
||||
decoration: InputDecoration(
|
||||
filled: true,
|
||||
fillColor: AppColors.background,
|
||||
border: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
borderSide: BorderSide(color: AppColors.border, width: 2),
|
||||
),
|
||||
focusedBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
borderSide: BorderSide(color: AppColors.primary, width: 2),
|
||||
),
|
||||
hintStyle: TextStyle(color: AppColors.textTertiary),
|
||||
contentPadding: EdgeInsets.symmetric(horizontal: 16, vertical: 12),
|
||||
),
|
||||
)
|
||||
```
|
||||
|
||||
### Skeleton Loading
|
||||
|
||||
```dart
|
||||
import '../../widgets/common/skeleton_loading.dart';
|
||||
|
||||
// Page skeleton
|
||||
const PageSkeleton(showHero: false, sectionCount: 3)
|
||||
|
||||
// Grid skeleton
|
||||
const SearchGridSkeleton(itemCount: 6)
|
||||
|
||||
// List skeleton
|
||||
const HorizontalListSkeleton(itemCount: 6)
|
||||
|
||||
// Card skeleton
|
||||
const ContentCardSkeleton()
|
||||
```
|
||||
|
||||
### Error Display
|
||||
|
||||
```dart
|
||||
import '../../widgets/common/error_display.dart';
|
||||
|
||||
// Inline error
|
||||
InlineError(
|
||||
message: 'Network error',
|
||||
onRetry: () => retry(),
|
||||
)
|
||||
|
||||
// Full error card
|
||||
ErrorDisplay(
|
||||
errorMessage: 'Failed to load',
|
||||
onRetry: () => retry(),
|
||||
)
|
||||
|
||||
// Snackbar
|
||||
ErrorSnackbar.show(
|
||||
context,
|
||||
'An error occurred',
|
||||
action: () => retry(),
|
||||
actionLabel: 'Retry',
|
||||
)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## ⚡ Animations Standard
|
||||
|
||||
```dart
|
||||
// Durées
|
||||
Duration(milliseconds: 150) // Fast - Micro-interactions
|
||||
Duration(milliseconds: 200) // Base - Hover, color
|
||||
Duration(milliseconds: 300) // Slow - Layout, modals
|
||||
|
||||
// Transition hover
|
||||
AnimatedContainer(
|
||||
duration: Duration(milliseconds: 200),
|
||||
curve: Curves.easeOut,
|
||||
decoration: /* ... */,
|
||||
)
|
||||
|
||||
// Page transition
|
||||
Navigator.push(
|
||||
context,
|
||||
PageRouteBuilder(
|
||||
pageBuilder: (context, animation, _) => NextPage(),
|
||||
transitionDuration: Duration(milliseconds: 300),
|
||||
transitionsBuilder: (context, animation, _, child) {
|
||||
return FadeTransition(
|
||||
opacity: animation,
|
||||
child: child,
|
||||
);
|
||||
},
|
||||
),
|
||||
)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🚨 Anti-Patterns (NE PAS FAIRE)
|
||||
|
||||
```dart
|
||||
❌ // Emojis comme icônes
|
||||
Icon(Icons.emoji_events)
|
||||
|
||||
✅ // Icônes Lucide/Heroicons
|
||||
Icon(Icons.music_note)
|
||||
|
||||
❌ // Text contrast faible
|
||||
TextStyle(color: Color(0xFF6A7294))
|
||||
|
||||
✅ // Contrast suffisant
|
||||
TextStyle(color: AppColors.textSecondary)
|
||||
|
||||
❌ // Transitions instantanées
|
||||
duration: Duration(milliseconds: 0)
|
||||
|
||||
✅ // Transitions fluides
|
||||
duration: Duration(milliseconds: 200)
|
||||
|
||||
❌ // Scale sur hover
|
||||
Transform.scale(scale: 1.02)
|
||||
|
||||
✅ // Color/shadow sur hover
|
||||
AnimatedContainer(
|
||||
decoration: BoxDecoration(
|
||||
boxShadow: [/* glow */],
|
||||
),
|
||||
)
|
||||
|
||||
❌ // Cursor manquant
|
||||
GestureDetector(onTap: () {}, child: Card())
|
||||
|
||||
✅ // Toujours ajouter cursor
|
||||
MouseRegion(
|
||||
cursor: SystemMouseCursors.click,
|
||||
child: GestureDetector(onTap: () {}, child: Card()),
|
||||
)
|
||||
|
||||
❌ // HTTP en production
|
||||
'http://api.example.com'
|
||||
|
||||
✅ // HTTPS
|
||||
'https://api.example.com'
|
||||
|
||||
❌ // Print en production
|
||||
print('Debug info')
|
||||
|
||||
✅ // Debug print
|
||||
if (kDebugMode) debugPrint('Debug info')
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📱 Responsive Breakpoints
|
||||
|
||||
```dart
|
||||
// Test largeur
|
||||
LayoutBuilder(
|
||||
builder: (context, constraints) {
|
||||
if (constraints.maxWidth >= 1024) {
|
||||
// Desktop
|
||||
} else if (constraints.maxWidth >= 768) {
|
||||
// Tablet
|
||||
} else {
|
||||
// Mobile
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
// Ou utiliser MediaQuery
|
||||
if (MediaQuery.of(context).size.width >= 1024) {
|
||||
// Desktop
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔧 Imports Rapides
|
||||
|
||||
```dart
|
||||
// Theme
|
||||
import '../../core/theme/colors.dart';
|
||||
import '../../core/theme/text_styles.dart';
|
||||
import '../../core/theme/app_theme.dart';
|
||||
|
||||
// Widgets communs
|
||||
import '../../widgets/common/clickable_wrapper.dart';
|
||||
import '../../widgets/common/skeleton_loading.dart';
|
||||
import '../../widgets/common/error_display.dart';
|
||||
|
||||
// Packages
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
import 'package:shimmer/shimmer.dart';
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## ✅ Checklist Avant Commit
|
||||
|
||||
- [ ] Pas d'emojis comme icônes
|
||||
- [ ] Cursor pointer sur éléments cliquables
|
||||
- [ ] Hover states avec 200ms
|
||||
- [ ] Contrast minimum 4.5:1
|
||||
- [ ] Focus states visibles
|
||||
- [ ] Animations 150-300ms
|
||||
- [ ] HTTPS pour URLs API
|
||||
- [ ] `debugPrint` au lieu de `print`
|
||||
- [ ] `CachedNetworkImage` pour images
|
||||
- [ ] Pas de scale sur hover
|
||||
|
||||
---
|
||||
|
||||
## 🎓 Règles d'Or
|
||||
|
||||
1. **Contraste avant tout** - Minimum 4.5:1
|
||||
2. **Feedback immédiat** - Toujours montrer hover/cursor
|
||||
3. **Transitions fluides** - 200ms standard
|
||||
4. **HTTPS par défaut** - Sécurité d'abord
|
||||
5. **Glow subtil** - Pas d'effets excessifs
|
||||
6. **Accessible** - WCAG AA compliant
|
||||
7. **Performant** - Animations optimisées
|
||||
8. **Cohérent** - Suivre le design system
|
||||
|
||||
---
|
||||
|
||||
**Besoin de plus de détails?** Voir le guide complet : `STYLE_GUIDE.md`
|
||||
|
||||
**Design system:** `design-system/MASTER.md`
|
||||
|
||||
**Implementation:** `DESIGN_IMPLEMENTATION_GUIDE.md`
|
||||
Reference in New Issue
Block a user