import 'package:easy_debounce/easy_debounce.dart'; import 'package:eatvio_app/features/diary/presentation/bloc/diary_cubit.dart'; import 'package:eatvio_app/features/diary/presentation/bloc/diary_state.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_rating_bar/flutter_rating_bar.dart'; import 'package:flutter_svg/flutter_svg.dart'; class MoodRatingWidget extends StatefulWidget { const MoodRatingWidget({super.key}); @override State createState() => _MoodRatingWidgetState(); } class _MoodRatingWidgetState extends State { List currentSelectedRating = [0, 0, 0, 0, 0]; List isFirstFetch = [true, true, true, true, true]; @override Widget build(BuildContext context) { return BlocBuilder( builder: (BuildContext context, DiaryState state) { if (state is DiaryStateLoaded) { final selectedIndex = state.selectedMeal - 1; final meals = state.diary.meals; if (selectedIndex >= 0 && selectedIndex < meals.length) { if (isFirstFetch[selectedIndex]) { currentSelectedRating[selectedIndex] = meals[selectedIndex].mood.toDouble() + 1; isFirstFetch[selectedIndex] = false; } } return Padding( padding: const EdgeInsets.only(top: 24), child: Column( mainAxisSize: MainAxisSize.min, children: [ Text( state.isConsultantView ? 'Настроение пользователя после приема пищи' : 'Ваше настроение после приёма пищи', textAlign: TextAlign.center, style: const TextStyle(fontSize: 16), ), Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ SvgPicture.asset('assets/icons/mood_1.svg', height: 32, width: 32), RatingBar.builder( ignoreGestures: state.isConsultantView || state.isDiaryFinished || state.isDiaryCommented, initialRating: (selectedIndex >= 0 && selectedIndex < state.diary.meals.length) ? state.diary.meals[selectedIndex].mood.toDouble() + 1 : 3, itemCount: 6, itemSize: MediaQuery.of(context).size.width / 6 - (124 / 6), updateOnDrag: true, itemBuilder: (context, index) { switch (index) { case 0: return Container( width: MediaQuery.of(context).size.width / 6, height: 24, margin: currentSelectedRating[selectedIndex] == 1 ? const EdgeInsets.symmetric(horizontal: 2) : null, decoration: BoxDecoration( color: const Color(0xFFC82222), border: currentSelectedRating[selectedIndex] == 1 ? Border.all(width: 2, color: const Color(0xFFAA3333), strokeAlign: BorderSide.strokeAlignOutside) : null, borderRadius: currentSelectedRating[selectedIndex] == 1 ? const BorderRadius.horizontal(left: Radius.circular(8), right: Radius.circular(2)) : const BorderRadius.horizontal(left: Radius.circular(8)), ), ); case 1: return Container( width: MediaQuery.of(context).size.width / 6, height: 24, margin: currentSelectedRating[selectedIndex] == 2 ? const EdgeInsets.symmetric(horizontal: 2) : null, decoration: BoxDecoration( color: const Color(0xFFFF3E3E), border: currentSelectedRating[selectedIndex] == 2 ? Border.all(width: 2, color: const Color(0xFF550000), strokeAlign: BorderSide.strokeAlignOutside) : null, borderRadius: currentSelectedRating[selectedIndex] == 2 ? BorderRadius.circular(2) : null, ), ); case 2: return Container( width: MediaQuery.of(context).size.width / 6, height: 24, margin: currentSelectedRating[selectedIndex] == 3 ? const EdgeInsets.symmetric(horizontal: 2) : null, decoration: BoxDecoration( color: const Color(0xFFF8C926), border: currentSelectedRating[selectedIndex] == 3 ? Border.all(width: 2, color: const Color(0xFF8C5D00), strokeAlign: BorderSide.strokeAlignOutside) : null, borderRadius: currentSelectedRating[selectedIndex] == 3 ? BorderRadius.circular(2) : null, ), ); case 3: return Container( width: MediaQuery.of(context).size.width / 6, height: 24, margin: currentSelectedRating[selectedIndex] == 4 ? const EdgeInsets.symmetric(horizontal: 2) : null, decoration: BoxDecoration( color: const Color(0xFFFFF3BF), border: currentSelectedRating[selectedIndex] == 4 ? Border.all(width: 2, color: const Color(0xFFB5911B), strokeAlign: BorderSide.strokeAlignOutside) : null, borderRadius: currentSelectedRating[selectedIndex] == 4 ? BorderRadius.circular(2) : null, ), ); case 4: return Container( width: MediaQuery.of(context).size.width / 6, height: 24, margin: currentSelectedRating[selectedIndex] == 5 ? const EdgeInsets.symmetric(horizontal: 2) : null, decoration: BoxDecoration( color: const Color(0xFF62E833), border: currentSelectedRating[selectedIndex] == 5 ? Border.all(width: 2, color: const Color(0xFF276918), strokeAlign: BorderSide.strokeAlignOutside) : null, borderRadius: currentSelectedRating[selectedIndex] == 5 ? BorderRadius.circular(2) : null, ), ); default: return Container( width: MediaQuery.of(context).size.width / 6, height: 24, margin: currentSelectedRating[selectedIndex] == 6 ? const EdgeInsets.symmetric(horizontal: 2) : null, decoration: BoxDecoration( color: const Color(0xFF4DCE20), border: currentSelectedRating[selectedIndex] == 6 ? Border.all(width: 2, color: const Color(0xFF184D12), strokeAlign: BorderSide.strokeAlignOutside) : null, borderRadius: currentSelectedRating[selectedIndex] == 6 ? const BorderRadius.horizontal(left: Radius.circular(2), right: Radius.circular(8)) : const BorderRadius.horizontal(right: Radius.circular(8)), ), ); } }, onRatingUpdate: (value) { setState(() { currentSelectedRating[selectedIndex] = value; }); EasyDebounce.debounce('change-satiety', const Duration(milliseconds: 250), () { context.read().fillMood(diaryId: state.diary.id, mood: currentSelectedRating[selectedIndex].toInt() - 1); }); }, ), SvgPicture.asset('assets/icons/mood_2.svg', height: 32, width: 32), ], ), ], ), ); } return const SizedBox.shrink(); }, ); } }