diff --git a/app/lib/widgets/dao/show_result_dialog.dart b/app/lib/widgets/dao/show_result_dialog.dart index ca325b1d7..b16d67b60 100644 --- a/app/lib/widgets/dao/show_result_dialog.dart +++ b/app/lib/widgets/dao/show_result_dialog.dart @@ -1,5 +1,6 @@ import 'package:flutter/material.dart'; import 'package:threebotlogin/services/tfchain_service.dart'; +import 'package:threebotlogin/widgets/custom_dialog.dart'; class ShowResultDialog extends StatefulWidget { final String proposalHash; @@ -179,11 +180,10 @@ class _ShowResultDialogState extends State ); } - return Dialog( - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(10), - ), - backgroundColor: Theme.of(context).colorScheme.surface, - child: content); + return CustomDialog( + title: 'Voting Result', + widgetDescription: content, + image: Icons.how_to_vote_outlined, + ); } } diff --git a/app/lib/widgets/dao/vote_dialog.dart b/app/lib/widgets/dao/vote_dialog.dart index e3f4b86b7..0b13a7bc9 100644 --- a/app/lib/widgets/dao/vote_dialog.dart +++ b/app/lib/widgets/dao/vote_dialog.dart @@ -81,115 +81,121 @@ class _VoteDialogState extends State { ), ); } else { - content = Padding( - padding: const EdgeInsets.all(30), - child: Flex( - direction: Axis.vertical, - mainAxisSize: MainAxisSize.min, - children: [ - DropdownMenu( - menuHeight: MediaQuery.sizeOf(context).height * 0.3, - enableFilter: true, - width: MediaQuery.sizeOf(context).width * 0.55, - textStyle: Theme.of(context).textTheme.bodyLarge!.copyWith( - color: Theme.of(context).colorScheme.onSurface, - ), - trailingIcon: const Icon( - CupertinoIcons.chevron_down, - size: 18, + if (farms.isEmpty) { + content = Text( + 'No farms available with online node to vote.', + style: Theme.of(context).textTheme.bodyLarge!.copyWith( + color: Theme.of(context).colorScheme.onSurface, ), - selectedTrailingIcon: const Icon( - CupertinoIcons.chevron_up, - size: 18, - ), - inputDecorationTheme: InputDecorationTheme( - filled: true, - fillColor: Theme.of(context).colorScheme.secondaryContainer, - enabledBorder: UnderlineInputBorder( - borderRadius: const BorderRadius.all(Radius.circular(4)), - borderSide: BorderSide( - color: Theme.of(context).colorScheme.secondaryContainer, - width: 8.0, - ), + textAlign: TextAlign.center, + ); + } else { + content = Padding( + padding: const EdgeInsets.all(30), + child: Flex( + direction: Axis.vertical, + mainAxisSize: MainAxisSize.min, + children: [ + DropdownMenu( + menuHeight: MediaQuery.sizeOf(context).height * 0.3, + enableFilter: true, + width: MediaQuery.sizeOf(context).width * 0.55, + textStyle: Theme.of(context).textTheme.bodyLarge!.copyWith( + color: Theme.of(context).colorScheme.onSurface, + ), + trailingIcon: const Icon( + CupertinoIcons.chevron_down, + size: 18, ), - ), - menuStyle: MenuStyle( - shape: WidgetStateProperty.all( - const RoundedRectangleBorder( - borderRadius: BorderRadius.all(Radius.circular(4)), + selectedTrailingIcon: const Icon( + CupertinoIcons.chevron_up, + size: 18, + ), + inputDecorationTheme: InputDecorationTheme( + filled: true, + fillColor: Theme.of(context).colorScheme.secondaryContainer, + enabledBorder: UnderlineInputBorder( + borderRadius: const BorderRadius.all(Radius.circular(4)), + borderSide: BorderSide( + color: Theme.of(context).colorScheme.secondaryContainer, + width: 8.0, + ), ), ), - ), - label: Text( - 'Select Farm', - style: Theme.of(context).textTheme.bodyLarge!.copyWith( - color: Theme.of(context).colorScheme.onSecondaryContainer, + menuStyle: MenuStyle( + shape: WidgetStateProperty.all( + const RoundedRectangleBorder( + borderRadius: BorderRadius.all(Radius.circular(4)), ), - ), - dropdownMenuEntries: _buildDropdownMenuEntries(farms), - onSelected: (int? value) { - if (value != null) { - farmId = value; - } - }, - ), - const SizedBox(height: 20), - Row( - mainAxisAlignment: MainAxisAlignment.spaceEvenly, - children: [ - ElevatedButton( - onPressed: () { - _vote(true); - }, - child: yesLoading - ? const SizedBox( - width: 20, - height: 20, - child: CircularProgressIndicator( - strokeWidth: 2, - )) - : Text( - 'Yes', - style: - Theme.of(context).textTheme.bodyLarge!.copyWith( - color: Theme.of(context) - .colorScheme - .onPrimaryContainer, - ), - ), + ), ), - ElevatedButton( - onPressed: () { - _vote(false); - }, - child: noLoading - ? const SizedBox( - width: 20, - height: 20, - child: CircularProgressIndicator( - strokeWidth: 2, - )) - : Text( - 'No', - style: - Theme.of(context).textTheme.bodyLarge!.copyWith( - color: Theme.of(context) - .colorScheme - .onPrimaryContainer, - ), - ), + label: Text( + 'Select Farm', + style: Theme.of(context).textTheme.bodyLarge!.copyWith( + color: + Theme.of(context).colorScheme.onSecondaryContainer, + ), ), - ], - ), - ], - ), - ); + dropdownMenuEntries: _buildDropdownMenuEntries(farms), + onSelected: (int? value) { + if (value != null) { + farmId = value; + } + }, + ), + ], + ), + ); + } } - return Dialog( - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(10), - ), - child: content); + return CustomDialog( + title: 'Vote', + widgetDescription: content, + image: Icons.how_to_vote_outlined, + actions: farms.isEmpty && !loading + ? [ + TextButton( + child: const Text('Close'), + onPressed: () { + Navigator.pop(context); + }, + ), + ] + : loading + ? null + : [ + TextButton( + child: noLoading + ? const SizedBox( + width: 20, + height: 20, + child: CircularProgressIndicator( + strokeWidth: 2, + ), + ) + : const Text('No'), + onPressed: () { + _vote(false); + }, + ), + TextButton( + child: yesLoading + ? const SizedBox( + width: 20, + height: 20, + child: CircularProgressIndicator( + strokeWidth: 2, + ), + ) + : const Text( + 'Yes', + ), + onPressed: () async { + _vote(true); + }, + ) + ], + ); } void _vote(bool approve) async { @@ -200,6 +206,20 @@ class _VoteDialogState extends State { final farm = farms.firstWhere((farm) => farm.farmID == farmId); final twinId = farm.twinId; final seed = twinIdWallets[twinId]!['tfchainSeed']; + final votes = await getProposalVotes(widget.proposalHash); + + final hasVotedYes = votes.ayes.any((vote) => vote.farmId == farmId); + final hasVotedNo = votes.nays.any((vote) => vote.farmId == farmId); + + if ((approve && hasVotedYes) || (!approve && hasVotedNo)) { + _showDialog('Voted!', 'You have voted successfully.', Icons.check, + DialogType.Info); + setState(() { + yesLoading = false; + noLoading = false; + }); + return; + } try { await vote(approve, widget.proposalHash, farmId!, seed!);