85dad89d5b
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>
411 lines
8.5 KiB
Markdown
411 lines
8.5 KiB
Markdown
# 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`
|