import 'dart:async'; import 'package:flutter/material.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:habitrack_app/function_widgets/widget_settings_menu/setting_entry.dart'; import 'package:habitrack_app/function_widgets/widget_settings_menu/widget_settings.dart'; import 'package:habitrack_app/infrastructure/widget_wall/items_controller.dart'; import 'package:habitrack_app/infrastructure/widget_wall/items_state.dart'; import 'package:habitrack_app/main.dart'; import 'package:habitrack_app/sembast/hydration.dart'; import 'package:liquid_progress_indicator_v2/liquid_progress_indicator.dart'; // ignore: must_be_immutable class CompoundWidgetWater extends ConsumerStatefulWidget { CompoundWidgetWater({required this.item, super.key}); late Hydration item; double getProgress() { return item.current / item.goal; } @override ConsumerState createState() => _CompoundWidgetWaterState(); } class _CompoundWidgetWaterState extends ConsumerState { void _toggleExpansion() { setState(() { widget.item = widget.item.copyWith(isExpanded: !widget.item.isExpanded); ref.watch(homeControllerProvider).edit(widget.item); }); } void _addQuantity(int toAdd) { setState(() { final controller = ref.watch(homeControllerProvider); final oldval = widget.item.current; logger.i('Old item: ${widget.item}'); widget.item = widget.item.copyWith(current: oldval + toAdd); logger.i('New item: ${widget.item}'); controller.edit(widget.item); }); } @override Widget build(BuildContext context) { ref.watch(itemsProvider); return Container( margin: const EdgeInsets.only(left: 10, top: 10, right: 10, bottom: 10), padding: const EdgeInsets.only(left: 10, top: 15, right: 10, bottom: 15), //height: 100, decoration: BoxDecoration( color: Theme.of(context).colorScheme.primary, borderRadius: const BorderRadius.all(Radius.circular(7)), boxShadow: [ BoxShadow( color: const Color(0x00000000).withOpacity(0.25), spreadRadius: 2, blurRadius: 5, // changes position of shadow ), ], ), width: double.infinity, child: Column( children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ if (!widget.item.isExpanded) ...[ Icon( Icons.local_drink, size: 20, color: Theme.of(context).colorScheme.onPrimary, ), Expanded( flex: 2, child: Container( margin: const EdgeInsets.only(left: 10, right: 10), // Width of the progress bar height: 30, // Height of the progress bar child: ClipRRect( borderRadius: const BorderRadius.all( Radius.circular(5), ), // Rounded corners child: LinearProgressIndicator( value: widget.getProgress(), // Progress value (0.0 - 1.0) backgroundColor: Colors.grey.withOpacity(0.5), // Background color valueColor: const AlwaysStoppedAnimation( Color(0xffA4E8FD), ), // Progress color ), ), ), ), Expanded( child: Text( widget.item.name, style: Theme.of(context).textTheme.bodyMedium!.copyWith( color: Theme.of(context).colorScheme.onPrimary, ), ), ), ], if (widget.item.isExpanded) ...[ Expanded( child: Text( widget.item.name, textScaler: const TextScaler.linear(2), style: Theme.of(context).textTheme.bodyMedium!.copyWith( color: Theme.of(context).colorScheme.onPrimary, ), ), ), Expanded( flex: 0, child: IconButton( icon: Icon( Icons.settings, color: Theme.of(context).colorScheme.onPrimary, ), onPressed: () => _showSettingsMenu(ref), ), //child: Icon(Icons.arrow_drop_down_circle_outlined), ), ], Expanded( flex: 0, child: IconButton( icon: Icon( widget.item.isExpanded ? Icons.arrow_drop_up_outlined : Icons.arrow_drop_down_circle_outlined, color: Theme.of(context).colorScheme.onPrimary, ), onPressed: _toggleExpansion, ), //child: Icon(Icons.arrow_drop_down_circle_outlined), ), ], ), if (widget.item.isExpanded) ...[ // Additional child elements when expanded SizedBox( height: 300, width: MediaQuery.of(context).size.width, child: Column( children: [ //INSERT WIDGET SPECIFIC STUFF HERE SizedBox( height: 300, width: MediaQuery.of(context).size.width, child: Row( children: [ Expanded( child: OvershootLiquidLinearProgressIndicator( current: widget.item.current, goal: widget.item.goal, ), ), Expanded( child: Column( children: [ Text( '${widget.item.current / 1000} / ${widget.item.goal / 1000} L', style: Theme.of(context) .textTheme .bodyMedium! .copyWith( color: Theme.of(context) .colorScheme .onPrimary, ), ), Expanded( child: OutlinedButton( style: ButtonStyle( backgroundColor: WidgetStateProperty.all( Theme.of(context).colorScheme.secondary, ), ), onPressed: () => { _addQuantity( widget.item.button1Amount, ), }, child: Text( '${widget.item.button1Amount} mL', style: Theme.of(context) .textTheme .bodyMedium! .copyWith( color: Theme.of(context) .colorScheme .onSecondary, ), ), ), ), Expanded( child: OutlinedButton( style: ButtonStyle( backgroundColor: WidgetStateProperty.all( Theme.of(context).colorScheme.secondary, ), ), onPressed: () => { _addQuantity( widget.item.button2Amount, ), }, child: Text( '${widget.item.button2Amount} mL', style: Theme.of(context) .textTheme .bodyMedium! .copyWith( color: Theme.of(context) .colorScheme .onPrimary, ), ), ), ), Expanded( child: OutlinedButton( style: ButtonStyle( backgroundColor: WidgetStateProperty.all( Theme.of(context).colorScheme.secondary, ), ), onPressed: _showPopupCustomAmount, child: Text( AppLocalizations.of(context)! .waterWidget_customAmountButton, style: Theme.of(context) .textTheme .bodyMedium! .copyWith( color: Theme.of(context) .colorScheme .onPrimary, ), ), ), ), ], ), ), ], ), ), ], ), ), // Add more widgets here as needed ], ], ), ); } Future _showSettingsMenu(WidgetRef ref) async { final settingEntries = WidgetSettingsData( entries: { 'name': SettingEntryText( name: AppLocalizations.of(context)!.widgetSettings_name, defaultValue: widget.item.name, ), 'button1Amount': SettingEntryNumeric( name: AppLocalizations.of(context)!.waterWidgetSettings_button1, defaultValue: widget.item.button1Amount, ), 'button2Amount': SettingEntryNumeric( name: AppLocalizations.of(context)!.waterWidgetSettings_button2, defaultValue: widget.item.button2Amount, ), 'targetGoal': SettingEntrySlider( name: AppLocalizations.of(context)!.waterWidgetSettings_goal, defaultValue: double.parse(widget.item.goal.toString()), divisions: 80, topValue: 4000, ), 'currentAmount': SettingEntryNumeric( name: AppLocalizations.of(context)!.waterWidgetSettings_current, defaultValue: widget.item.current, ), }, ); return showDialog( context: context, barrierDismissible: false, builder: (BuildContext context) { return AlertDialog( backgroundColor: Theme.of(context).colorScheme.primaryContainer, content: WidgetSettings( entries: settingEntries, ), actions: [ OutlinedButton( style: OutlinedButton.styleFrom( backgroundColor: Colors.red, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(12), ), ), onPressed: () { //widget.parent.delete(ref); ref.watch(itemsProvider); final controller = ref.watch(homeControllerProvider); widget.item = widget.item.copyWith(isVisible: false); controller.edit(widget.item); logger.i('Attempting delete'); // ignore: use_build_context_synchronously Navigator.of(context).pop(); }, child: Text( AppLocalizations.of(context)!.widgetSettings_deleteButton, style: Theme.of(context).textTheme.bodyMedium!.copyWith( color: Theme.of(context).colorScheme.onPrimary, fontWeight: FontWeight.bold, ), ), ), ElevatedButton( style: ElevatedButton.styleFrom( backgroundColor: Theme.of(context).colorScheme.onPrimary, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(12), ), ), onPressed: () { final controller = ref.watch(homeControllerProvider); logger.i('Attempting edit of water widget stuff'); // widget.settingEntries.notify(); final name = settingEntries.getValue('name') as String; final currentAmount = settingEntries.getValue('currentAmount') as int; final targetGoal = (settingEntries.getValue('targetGoal') as double).round(); final button1Amount = settingEntries.getValue('button1Amount') as int; final button2Amount = settingEntries.getValue('button2Amount') as int; widget.item = widget.item.copyWith( name: name, current: currentAmount, goal: targetGoal, button1Amount: button1Amount, button2Amount: button2Amount, ); controller.edit(widget.item); Navigator.of(context).pop(); }, child: Text( AppLocalizations.of(context)!.widgetSettings_saveButton, style: Theme.of(context).textTheme.bodyMedium!.copyWith( color: Theme.of(context).colorScheme.primary, fontWeight: FontWeight.bold, ), ), ), ], ); }, ); } Future _showPopupCustomAmount() async { final customFieldController = TextEditingController(); return showDialog( context: context, barrierDismissible: false, builder: (BuildContext context) { return AlertDialog( scrollable: true, backgroundColor: Theme.of(context).colorScheme.primaryContainer, title: Text( AppLocalizations.of(context)!.waterWidget_customAmountMessage, style: Theme.of(context).textTheme.bodyMedium!.copyWith( color: Theme.of(context).colorScheme.onPrimaryContainer, ), ), content: Column( children: [ TextField( controller: customFieldController, keyboardType: TextInputType.number, autofocus: true, ), ], ), actions: [ ElevatedButton( style: ElevatedButton.styleFrom( shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(12), ), backgroundColor: Theme.of(context).colorScheme.primary, ), onPressed: () { Navigator.of(context).pop(); }, child: Text( AppLocalizations.of(context)!.widgetSettings_cancelButton, style: Theme.of(context).textTheme.bodyMedium!.copyWith( color: Theme.of(context).colorScheme.onPrimary, ), ), ), ElevatedButton( style: ElevatedButton.styleFrom( backgroundColor: Theme.of(context).colorScheme.primary, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(12), ), ), onPressed: () { Navigator.of(context).pop(); final result = int.tryParse(customFieldController.text) ?? 0; _addQuantity(result); }, child: Text( AppLocalizations.of(context)!.widgetSettings_saveButton, style: Theme.of(context).textTheme.bodyMedium!.copyWith( color: Theme.of(context).colorScheme.onPrimary, ), ), ), ], ); }, ); } } class OvershootLiquidLinearProgressIndicator extends StatelessWidget { const OvershootLiquidLinearProgressIndicator({ required this.current, required this.goal, super.key, }); final int current; final int goal; @override Widget build(BuildContext context) { var mainColor = Colors.blue; var backColor = Colors.white; var value = 0.0; if (current < goal) { mainColor = Colors.blue; backColor = Colors.white; value = (current - goal * 0) / goal; } else if (current < goal * 2) { mainColor = Colors.orange; backColor = Colors.blue; value = (current - goal * 1) / goal; } else { mainColor = Colors.red; backColor = Colors.orange; value = (current - goal * 2) / goal; } return LiquidLinearProgressIndicator( value: value, valueColor: AlwaysStoppedAnimation( mainColor, ), backgroundColor: backColor, borderColor: Colors.black, borderWidth: 3, borderRadius: 12, direction: Axis.vertical, ); } }