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>
8.5 KiB
8.5 KiB
AudiOhm - Quick Reference Guide
Pour les développeurs - Référence rapide pour les tâches courantes
🎨 Couleurs les Plus Utilisées
// 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
// 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
display: 48px // Hero
h1: 36px // Page title
h2: 28px // Section
h3: 22px // Card title
body: 16px // Standard
small: 14px // Secondary
caption: 12px // Metadata
📏 Spacing
// 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
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
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
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
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
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
// 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)
❌ // 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
// 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
// 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
debugPrintau lieu deprintCachedNetworkImagepour images- Pas de scale sur hover
�� Règles d'Or
- Contraste avant tout - Minimum 4.5:1
- Feedback immédiat - Toujours montrer hover/cursor
- Transitions fluides - 200ms standard
- HTTPS par défaut - Sécurité d'abord
- Glow subtil - Pas d'effets excessifs
- Accessible - WCAG AA compliant
- Performant - Animations optimisées
- 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