diff --git a/lib/screens/camera_screen.dart b/lib/screens/camera_screen.dart index d7ed7b8..17446b3 100644 --- a/lib/screens/camera_screen.dart +++ b/lib/screens/camera_screen.dart @@ -11,6 +11,7 @@ import 'package:gal/gal.dart'; import '../services/gemini_service.dart'; import '../services/image_compression_service.dart'; // Phase 4 Added +import '../services/gamification_service.dart'; // Badge check import '../widgets/analyzing_dialog.dart'; import '../models/sake_item.dart'; import '../theme/app_theme.dart'; @@ -386,9 +387,12 @@ class _CameraScreenState extends ConsumerState with SingleTickerPr // Award EXP final userProfileState = ref.read(userProfileProvider); final prevLevel = userProfileState.level; - + await ref.read(userProfileProvider.notifier).updateTotalExp(userProfileState.totalExp + 10); - + + // Check and unlock badges + final newBadges = await GamificationService.checkAndUnlockBadges(ref); + // Refetch updated state for level comparison final updatedProfile = ref.read(userProfileProvider); final newLevel = updatedProfile.level; @@ -408,28 +412,49 @@ class _CameraScreenState extends ConsumerState with SingleTickerPr // Close Camera Screen (Return to Home) Navigator.of(context).pop(); - // Success Message (with EXP/Level Up info) + // Success Message (with EXP/Level Up/Badge info) + final List messageWidgets = [ + Text('${sakeItem.displayData.name} を登録しました!'), + const SizedBox(height: 4), + Row( + children: [ + const Icon(LucideIcons.sparkles, color: Colors.yellow, size: 16), + const SizedBox(width: 8), + Text( + '経験値 +10 GET! ${isLevelUp ? " (Level UP!)" : ""}', + style: const TextStyle(fontWeight: FontWeight.bold, color: Colors.yellowAccent), + ), + ], + ), + ]; + + // Add badge notifications + if (newBadges.isNotEmpty) { + messageWidgets.add(const SizedBox(height: 8)); + for (var badge in newBadges) { + messageWidgets.add( + Row( + children: [ + Text(badge.icon, style: const TextStyle(fontSize: 16)), + const SizedBox(width: 8), + Text( + 'バッジ獲得: ${badge.name}', + style: const TextStyle(fontWeight: FontWeight.bold, color: Colors.greenAccent), + ), + ], + ), + ); + } + } + ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text('${sakeItem.displayData.name} を登録しました!'), - const SizedBox(height: 4), - Row( - children: [ - const Icon(LucideIcons.sparkles, color: Colors.yellow, size: 16), - const SizedBox(width: 8), - Text( - '経験値 +10 GET! ${isLevelUp ? " (Level UP!)" : ""}', - style: const TextStyle(fontWeight: FontWeight.bold, color: Colors.yellowAccent), - ), - ], - ), - ], + children: messageWidgets, ), - duration: const Duration(seconds: 4), // Longer display for level up + duration: Duration(seconds: newBadges.isNotEmpty ? 6 : 4), // Longer for badges ), ); @@ -793,12 +818,10 @@ class _ExposureSliderPainter extends CustomPainter { // Draw knob canvas.drawCircle(Offset(trackX, knobY), 6, knobPaint); } - } - - @override + } @override bool shouldRepaint(_ExposureSliderPainter oldDelegate) { return oldDelegate.currentValue != currentValue || oldDelegate.minValue != minValue || oldDelegate.maxValue != maxValue; } -} \ No newline at end of file +}