diff --git a/lib/core/extension/proposal_details_model_extension.dart b/lib/core/extension/proposal_details_model_extension.dart deleted file mode 100644 index 6db36603..00000000 --- a/lib/core/extension/proposal_details_model_extension.dart +++ /dev/null @@ -1,95 +0,0 @@ -import 'package:hypha_wallet/core/network/models/proposal_details_model.dart'; -import 'package:intl/intl.dart'; - -extension ProposalDetailsModelExtension on ProposalDetailsModel { - double tokenMixToPercent() => - tokenMixPercentage == null ? 0 : tokenMixPercentage! * .01; - - String formatCycleStartDate() => cycleStartDate != null - ? DateFormat('EEEE, MMMM yyyy').format(cycleStartDate!) - : ''; - - String cycleEndDate() => DateFormat('EEEE, MMMM yyyy') - .format(cycleStartDate!.add(Duration(days: cycleCount! * 7))); - - String? tokenTitle(int index) { - String input; - - switch (index) { - case 0: - input = utilityAmount ?? utilityAmountPerPeriod!; - break; - case 1: - input = voiceAmount ?? voiceAmountPerPeriod!; - break; - case 2: - input = cashAmount ?? cashAmountPerPeriod!; - break; - default: - return null; - } - - final RegExp regExp = RegExp(r'\d+\s+(.*)'); - final match = regExp.firstMatch(input); - - if (match != null) { - String result = match.group(1)!; - - if (result.isNotEmpty && index != 0) { - result = result[0].toLowerCase() + result.substring(1); - } - return result; - } - return null; - } - - double? tokenValue(int index, bool isOneCycleRewardsShown) { - double? tokenAmount; - double? tokenAmountPerPeriod; - final int cycleDurationSec = 2629800; - final double periodsOnCycle = cycleDurationSec / periodDurationSec!; - switch (index) { - case 0: - tokenAmount = utilityAmountDouble; - tokenAmountPerPeriod = utilityAmountPerPeriodDouble; - break; - case 1: - tokenAmount = voiceAmountDouble; - tokenAmountPerPeriod = voiceAmountPerPeriodDouble; - break; - case 2: - tokenAmount = cashAmountDouble; - tokenAmountPerPeriod = cashAmountPerPeriodDouble; - - break; - default: - return null; - } - if (tokenAmount != null) { - if (isOneCycleRewardsShown) return tokenAmount; - return tokenAmount / periodsOnCycle; - } - if (tokenAmountPerPeriod != null) { - if (isOneCycleRewardsShown) { - return tokenAmountPerPeriod * periodsOnCycle; - } - return tokenAmountPerPeriod; - } - return tokenAmount; - } -} - -extension TokenTypeExtension on TokenType { - String get name { - switch (this) { - case TokenType.utility: - return 'Utility Token'; - case TokenType.voice: - return 'Voice Token'; - case TokenType.cash: - return 'Cash Token'; - default: - return ''; - } - } -} diff --git a/lib/core/network/api/services/proposal_service.dart b/lib/core/network/api/services/proposal_service.dart index b89b7a86..390f3154 100644 --- a/lib/core/network/api/services/proposal_service.dart +++ b/lib/core/network/api/services/proposal_service.dart @@ -20,10 +20,8 @@ class ProposalService { return _graphQLService.graphQLQuery(network: user.network, query: query); } - Future, HyphaError>> getProposalDetails( - String proposalId, UserProfileData user) async { - final String query = - '{"query":"query proposalDetails(\$docId: String!) { getDocument(docId: \$docId) {__typename docId creator createdDate ... on Votable { votetally { ... on VoteTally { pass_votePower_a fail_votePower_a abstain_votePower_a } } pass: voteAggregate(filter: { vote_vote_s: { regexp: \\"/.*pass*./\\" } }) {count} fail: voteAggregate(filter: { vote_vote_s: { regexp: \\"/.*fail*./\\" } }) {count} vote { ... on Vote { vote_voter_n vote_vote_s } } } ... on Edit {details_title_s details_description_s details_periodCount_i details_deferredPercX100_i ballot_expiration_t dao {docId settings {settings_daoTitle_s settings_periodDurationSec_i}} details_ballotAlignment_i details_ballotQuorum_i} ... on Queststart {details_title_s details_description_s details_periodCount_i details_deferredPercX100_i start {details_startTime_t} ballot_expiration_t dao {docId settings {settings_daoTitle_s settings_periodDurationSec_i}} details_ballotAlignment_i details_ballotSupply_a details_ballotQuorum_i details_pegAmount_a details_voiceAmount_a details_rewardAmount_a} ... on Questcomple {details_title_s details_description_s ballot_expiration_t dao {docId settings {settings_daoTitle_s settings_periodDurationSec_i}} details_pegAmount_a details_voiceAmount_a details_rewardAmount_a} ... on Policy {details_title_s details_description_s details_periodCount_i details_deferredPercX100_i ballot_expiration_t dao {docId settings {settings_daoTitle_s settings_periodDurationSec_i}} details_ballotAlignment_i details_ballotSupply_a details_ballotQuorum_i details_pegAmount_a details_voiceAmount_a details_rewardAmount_a} ... on Payout {details_title_s details_description_s details_periodCount_i details_deferredPercX100_i start {details_startTime_t} ballot_expiration_t dao {docId settings {settings_daoTitle_s settings_periodDurationSec_i}} details_ballotAlignment_i details_ballotSupply_a details_ballotQuorum_i details_pegAmount_a details_voiceAmount_a details_rewardAmount_a} ... on Badge {details_title_s details_description_s details_periodCount_i ballot_expiration_t dao {docId settings {settings_daoTitle_s settings_periodDurationSec_i}} details_ballotAlignment_i details_ballotSupply_a details_ballotQuorum_i} ... on Poll {details_title_s details_description_s ballot_expiration_t dao {docId settings {settings_daoTitle_s settings_periodDurationSec_i}} details_ballotAlignment_i details_ballotSupply_a details_ballotQuorum_i} ... on Budget {details_title_s details_description_s details_deferredPercX100_i ballot_expiration_t dao {docId settings {settings_daoTitle_s settings_periodDurationSec_i}} details_ballotAlignment_i details_ballotSupply_a details_ballotQuorum_i details_pegAmount_a details_voiceAmount_a details_rewardAmount_a} ... on Assignment {details_title_s details_description_s details_periodCount_i details_deferredPercX100_i start {details_startTime_t} details_rewardSalaryPerPeriod_a details_voiceSalaryPerPeriod_a details_pegSalaryPerPeriod_a ballot_expiration_t dao {docId settings {settings_daoTitle_s settings_periodDurationSec_i}} details_timeShareX100_i details_ballotAlignment_i details_ballotSupply_a details_ballotQuorum_i} } }", "variables":{"docId":"$proposalId"}}'; + Future, HyphaError>> getProposalDetails(String proposalId, UserProfileData user) async { + final String query = '{"query":"query proposalDetails(\$docId: String!) { getDocument(docId: \$docId) {docId creator ... on Votable { votetally { ... on VoteTally { pass_votePower_a fail_votePower_a abstain_votePower_a } } pass: voteAggregate(filter: { vote_vote_s: { regexp: \\"/.*pass*./\\" } }) {count} fail: voteAggregate(filter: { vote_vote_s: { regexp: \\"/.*fail*./\\" } }) {count} vote { ... on Vote { vote_voter_n vote_vote_s } } } ... on Edit {details_title_s details_description_s ballot_expiration_t dao {docId } details_ballotAlignment_i details_ballotQuorum_i} ... on Queststart {details_title_s details_description_s ballot_expiration_t dao {docId} details_ballotAlignment_i details_ballotSupply_a details_ballotQuorum_i} ... on Questcomple {details_title_s details_description_s ballot_expiration_t dao {docId}} ... on Policy {details_title_s details_description_s ballot_expiration_t dao {docId} details_ballotAlignment_i details_ballotSupply_a details_ballotQuorum_i} ... on Payout {details_title_s details_description_s ballot_expiration_t dao {docId} details_ballotAlignment_i details_ballotSupply_a details_ballotQuorum_i} ... on Badge {details_title_s details_description_s dao {docId} details_ballotAlignment_i details_ballotSupply_a details_ballotQuorum_i} ... on Poll {details_title_s details_description_s ballot_expiration_t dao {docId} details_ballotAlignment_i details_ballotSupply_a details_ballotQuorum_i} ... on Budget {details_title_s details_description_s ballot_expiration_t dao {docId} details_ballotAlignment_i details_ballotSupply_a details_ballotQuorum_i} ... on Assignment {details_title_s details_description_s ballot_expiration_t dao {docId} details_timeShareX100_i details_ballotAlignment_i details_ballotSupply_a details_ballotQuorum_i} } }", "variables":{"docId":"$proposalId"}}'; return _graphQLService.graphQLQuery(network: user.network, query: query); } diff --git a/lib/core/network/models/dao_proposals_model.dart b/lib/core/network/models/dao_proposals_model.dart deleted file mode 100644 index 0fbe3ef6..00000000 --- a/lib/core/network/models/dao_proposals_model.dart +++ /dev/null @@ -1,8 +0,0 @@ -import 'package:hypha_wallet/core/network/models/dao_data_model.dart'; -import 'package:hypha_wallet/core/network/models/proposal_model.dart'; - -class DaoProposalsModel { - final DaoData dao; - final List proposals; - DaoProposalsModel({required this.dao, required this.proposals}); -} diff --git a/lib/core/network/models/proposal_details_model.dart b/lib/core/network/models/proposal_details_model.dart index f05744d6..34210519 100644 --- a/lib/core/network/models/proposal_details_model.dart +++ b/lib/core/network/models/proposal_details_model.dart @@ -1,4 +1,3 @@ -import 'package:hypha_wallet/core/extension/string_extension.dart'; import 'package:hypha_wallet/core/extension/vote_tally_extension.dart'; import 'package:hypha_wallet/core/network/models/base_proposal_model.dart'; import 'package:hypha_wallet/core/network/models/dao_data_model.dart'; @@ -8,72 +7,13 @@ import 'package:json_annotation/json_annotation.dart'; part 'proposal_details_model.g.dart'; -enum TokenType { - utility, - voice, - cash, -} - @JsonSerializable() class ProposalDetailsModel extends BaseProposalModel { - double? get utilityAmountDouble => utilityAmount?.quantityAsDouble; - - double? get voiceAmountDouble => voiceAmount?.quantityAsDouble; - - double? get cashAmountDouble => cashAmount?.quantityAsDouble; - - double? get utilityAmountPerPeriodDouble => - utilityAmountPerPeriod?.quantityAsDouble; - - double? get voiceAmountPerPeriodDouble => - voiceAmountPerPeriod?.quantityAsDouble; - - double? get cashAmountPerPeriodDouble => - cashAmountPerPeriod?.quantityAsDouble; - - @JsonKey(name: '__typename') - final String type; - - @JsonKey(name: 'settings_periodDurationSec_i') - final int? periodDurationSec; - - @JsonKey(name: 'createdDate') - final DateTime creationDate; - - @JsonKey(name: 'details_deferredPercX100_i') - final int? tokenMixPercentage; - - @JsonKey(name: 'details_periodCount_i') - final int? cycleCount; - - @JsonKey(name: 'start') - final DateTime? cycleStartDate; - - @JsonKey(name: 'details_rewardAmount_a') - final String? utilityAmount; - - @JsonKey(name: 'details_voiceAmount_a') - final String? voiceAmount; - - @JsonKey(name: 'details_pegAmount_a') - final String? cashAmount; - - @JsonKey(name: 'details_rewardSalaryPerPeriod_a') - final String? utilityAmountPerPeriod; - - @JsonKey(name: 'details_voiceSalaryPerPeriod_a') - final String? voiceAmountPerPeriod; - - @JsonKey(name: 'details_pegSalaryPerPeriod_a') - final String? cashAmountPerPeriod; - @JsonKey(name: 'details_description_s') final String? description; ProposalDetailsModel( {required super.id, - required this.type, - required this.creationDate, super.dao, super.commitment, super.title, @@ -84,39 +24,10 @@ class ProposalDetailsModel extends BaseProposalModel { super.expiration, super.creator, super.votes, - this.tokenMixPercentage, - this.cycleCount, - this.cycleStartDate, - this.utilityAmount, - this.voiceAmount, - this.cashAmount, - this.utilityAmountPerPeriod, - this.voiceAmountPerPeriod, - this.cashAmountPerPeriod, this.description, - this.periodDurationSec}); + }); factory ProposalDetailsModel.fromJson(Map json) { - // Handle the 'start' field if it's a list - if (json['start'] is List) { - if ((json['start'] as List).isNotEmpty) { - json['start'] = json['start'][0]['details_startTime_t']; - } else { - json['start'] = null; - } - } - if (json['dao'] is List) { - final daoList = json['dao']; - if (daoList.isNotEmpty && - daoList[0] is Map && - daoList[0]['settings'] is List) { - final settingsList = daoList[0]['settings'] as List; - if (settingsList.isNotEmpty && settingsList[0] is Map) { - json['settings_periodDurationSec_i'] = - settingsList[0]['settings_periodDurationSec_i']; - } - } - } json['dao'] = null; json['creator'] = null; diff --git a/lib/core/network/models/proposal_details_model.g.dart b/lib/core/network/models/proposal_details_model.g.dart index fa1e06a8..a2cf2af8 100644 --- a/lib/core/network/models/proposal_details_model.g.dart +++ b/lib/core/network/models/proposal_details_model.g.dart @@ -10,8 +10,6 @@ ProposalDetailsModel _$ProposalDetailsModelFromJson( Map json) => ProposalDetailsModel( id: json['docId'] as String, - type: json['__typename'] as String, - creationDate: DateTime.parse(json['createdDate'] as String), dao: json['dao'] == null ? null : DaoData.fromJson(json['dao'] as Map), @@ -30,21 +28,7 @@ ProposalDetailsModel _$ProposalDetailsModelFromJson( votes: (json['vote'] as List?) ?.map((e) => VoteModel.fromJson(e as Map)) .toList(), - tokenMixPercentage: (json['details_deferredPercX100_i'] as num?)?.toInt(), - cycleCount: (json['details_periodCount_i'] as num?)?.toInt(), - cycleStartDate: json['start'] == null - ? null - : DateTime.parse(json['start'] as String), - utilityAmount: json['details_rewardAmount_a'] as String?, - voiceAmount: json['details_voiceAmount_a'] as String?, - cashAmount: json['details_pegAmount_a'] as String?, - utilityAmountPerPeriod: - json['details_rewardSalaryPerPeriod_a'] as String?, - voiceAmountPerPeriod: json['details_voiceSalaryPerPeriod_a'] as String?, - cashAmountPerPeriod: json['details_pegSalaryPerPeriod_a'] as String?, description: json['details_description_s'] as String?, - periodDurationSec: - (json['settings_periodDurationSec_i'] as num?)?.toInt(), ); Map _$ProposalDetailsModelToJson( @@ -61,17 +45,5 @@ Map _$ProposalDetailsModelToJson( 'ballot_expiration_t': instance.expiration?.toIso8601String(), 'creator': instance.creator, 'vote': instance.votes, - '__typename': instance.type, - 'settings_periodDurationSec_i': instance.periodDurationSec, - 'createdDate': instance.creationDate.toIso8601String(), - 'details_deferredPercX100_i': instance.tokenMixPercentage, - 'details_periodCount_i': instance.cycleCount, - 'start': instance.cycleStartDate?.toIso8601String(), - 'details_rewardAmount_a': instance.utilityAmount, - 'details_voiceAmount_a': instance.voiceAmount, - 'details_pegAmount_a': instance.cashAmount, - 'details_rewardSalaryPerPeriod_a': instance.utilityAmountPerPeriod, - 'details_voiceSalaryPerPeriod_a': instance.voiceAmountPerPeriod, - 'details_pegSalaryPerPeriod_a': instance.cashAmountPerPeriod, 'details_description_s': instance.description, }; diff --git a/lib/core/network/repository/proposal_repository.dart b/lib/core/network/repository/proposal_repository.dart index fcc4356c..a1525c68 100644 --- a/lib/core/network/repository/proposal_repository.dart +++ b/lib/core/network/repository/proposal_repository.dart @@ -1,12 +1,13 @@ +import 'package:hypha_wallet/core/crypto/seeds_esr/eos_action.dart'; import 'package:hypha_wallet/core/error_handler/model/hypha_error.dart'; import 'package:hypha_wallet/core/extension/base_proposal_model_extension.dart'; import 'package:hypha_wallet/core/logging/log_helper.dart'; import 'package:hypha_wallet/core/network/api/actions/vote_action_factory.dart'; +import 'package:hypha_wallet/core/network/api/eos_service.dart'; import 'package:hypha_wallet/core/network/api/services/dao_service.dart'; import 'package:hypha_wallet/core/network/api/services/proposal_service.dart'; import 'package:hypha_wallet/core/network/api/services/remote_config_service.dart'; import 'package:hypha_wallet/core/network/models/dao_data_model.dart'; -import 'package:hypha_wallet/core/network/models/dao_proposals_model.dart'; import 'package:hypha_wallet/core/network/models/network.dart'; import 'package:hypha_wallet/core/network/models/proposal_details_model.dart'; import 'package:hypha_wallet/core/network/models/proposal_model.dart'; @@ -18,9 +19,6 @@ import 'package:hypha_wallet/ui/profile/interactor/profile_data.dart'; import 'package:hypha_wallet/ui/proposals/filter/interactor/filter_status.dart'; import 'package:hypha_wallet/ui/proposals/list/interactor/get_proposals_use_case_input.dart'; -import '../../crypto/seeds_esr/eos_action.dart'; -import '../api/eos_service.dart'; - class ProposalRepository { final ProposalService _proposalService; final ProfileService _profileService; @@ -28,25 +26,20 @@ class ProposalRepository { final EOSService _eosService; final RemoteConfigService _remoteConfigService; - - ProposalRepository( this._remoteConfigService, this._eosService, this._daoService, this._proposalService, this._profileService); - Future, HyphaError>> getProposals( - UserProfileData user, GetProposalsUseCaseInput input) async { - final List, HyphaError>>> futures = - input.daos.map((DaoData dao) { + Future, HyphaError>> getProposals(UserProfileData user, GetProposalsUseCaseInput input) async { + final List, HyphaError>>> futures = input.daos.map((DaoData dao) { return input.filterStatus == FilterStatus.active ? _proposalService.getActiveProposals(user, dao.docId) : _proposalService.getPastProposals(user, dao.docId); }).toList(); - final List, HyphaError>> futureResults = - await Future.wait(futures); + final List, HyphaError>> futureResults = await Future.wait(futures); final List allProposals = []; @@ -62,15 +55,11 @@ class ProposalRepository { } try { - final List proposals = - await _parseProposalsFromResponse( - response, input.daos[i], input.filterStatus); + final List proposals = await _parseProposalsFromResponse(response, input.daos[i], input.filterStatus); allProposals.addAll(proposals); } catch (e, stackTrace) { - LogHelper.e('Error parsing data into proposal model', - error: e, stacktrace: stackTrace); - return Result.error( - HyphaError.generic('Error parsing data into proposal model')); + LogHelper.e('Error parsing data into proposal model', error: e, stacktrace: stackTrace); + return Result.error(HyphaError.generic('Error parsing data into proposal model')); } } else { LogHelper.e('GraphQL query failed', error: result.asError!.error); @@ -82,69 +71,16 @@ class ProposalRepository { return Result.value(allProposals); } - Future, HyphaError>> getHistoryProposalsPerDao( - UserProfileData user, GetProposalsUseCaseInput input) async { - // Fetch past proposals for all DAOs - final List, HyphaError>>> futures = - input.daos.map((DaoData dao) { - return _proposalService.getPastProposals( - user, dao.docId); // Fetch proposals using integer docId - }).toList(); - - final List, HyphaError>> futureResults = - await Future.wait(futures); - - final List daoProposalsList = []; - - for (int i = 0; i < futureResults.length; i++) { - final Result, HyphaError> result = futureResults[i]; - - if (result.isValue) { - final Map response = result.asValue!.value; - if (response['errors'] != null) { - LogHelper.e('GraphQL query failed', error: response['errors']); - return Result.error(HyphaError.api('GraphQL query failed')); - } - - try { - // Parse proposals for the current DAO - final List proposals = - await _parseProposalsFromResponse( - response, input.daos[i], input.filterStatus); - - // Create a DaoProposalsModel instance with the current DAO and its proposals - daoProposalsList - .add(DaoProposalsModel(dao: input.daos[i], proposals: proposals)); - } catch (e, stackTrace) { - LogHelper.e('Error parsing data into proposal model', - error: e, stacktrace: stackTrace); - return Result.error( - HyphaError.generic('Error parsing data into proposal model')); - } - } else { - LogHelper.e('GraphQL query failed', error: result.asError!.error); - return Result.error(result.asError!.error); - } - } - - // Return the list of DaoProposalsModel - return Result.value(daoProposalsList); - } - Future> _parseProposalsFromResponse( Map response, DaoData daoData, FilterStatus filterStatus) async { final List proposalsData = response['data']['queryDao']; - final List> proposalFutures = - proposalsData.expand((dao) { - final List proposals = - dao[filterStatus == FilterStatus.active ? 'proposal' : 'votable'] - as List; + final List> proposalFutures = proposalsData.expand((dao) { + final List proposals = dao[filterStatus == FilterStatus.active ? 'proposal' : 'votable'] as List; return proposals.map((dynamic proposal) async { - final Result creator = - await _profileService.getProfile(proposal['creator']); + final Result creator = await _profileService.getProfile(proposal['creator']); proposal['creator'] = null; final ProposalModel proposalModel = ProposalModel.fromJson(proposal); @@ -181,14 +117,12 @@ class ProposalRepository { }); } - Future> getProposalDetails( - String proposalId, UserProfileData user) async { - final Result, HyphaError> result = - await _proposalService.getProposalDetails(proposalId, user); + Future> getProposalDetails(String proposalId, UserProfileData user) async { + final Result, HyphaError> result = await _proposalService.getProposalDetails(proposalId, user); + if (result.isValue) { if (result.asValue!.value['errors'] != null) { - LogHelper.e('GraphQL query failed', - error: result.asValue!.value['errors']); + LogHelper.e('GraphQL query failed', error: result.asValue!.value['errors']); return Result.error(HyphaError.api('GraphQL query failed')); } @@ -196,27 +130,23 @@ class ProposalRepository { final Map response = result.valueOrCrash; final Result dao= await _daoService.getDaoById(network: Network.telos, daoId:response['data']['getDocument']['dao'][0]['docId'] ); final Result creator = await _profileService.getProfile(response['data']['getDocument']['creator']); - final ProposalDetailsModel proposalDetails = - ProposalDetailsModel.fromJson(response['data']['getDocument']); + final ProposalDetailsModel proposalDetails = ProposalDetailsModel.fromJson(response['data']['getDocument']); + if (proposalDetails.votes != null) { for (int i = 0; i < proposalDetails.votes!.length; i++) { - final Result voterData = - await _profileService - .getProfile(proposalDetails.votes![i].voter); + final Result voterData = await _profileService.getProfile(proposalDetails.votes![i].voter); if (voterData.isValue) { - proposalDetails.votes![i].voterImageUrl = - voterData.asValue!.value.avatarUrl; + proposalDetails.votes![i].voterImageUrl = voterData.asValue!.value.avatarUrl; } } } + proposalDetails.creator=creator.asValue!.value; proposalDetails.dao=dao.asValue!.value; return Result.value(proposalDetails); } catch (e, stackTrace) { - LogHelper.e('Error parsing data into proposal details model', - error: e, stacktrace: stackTrace); - return Result.error(HyphaError.generic( - 'Error parsing data into details proposal model')); + LogHelper.e('Error parsing data into proposal details model', error: e, stacktrace: stackTrace); + return Result.error(HyphaError.generic('Error parsing data into details proposal model')); } } else { LogHelper.e('GraphQL query failed', error: result.asError!.error); diff --git a/lib/ui/proposals/components/proposal_creator.dart b/lib/ui/proposals/components/proposal_creator.dart index c2da97c2..fe7cc5ed 100644 --- a/lib/ui/proposals/components/proposal_creator.dart +++ b/lib/ui/proposals/components/proposal_creator.dart @@ -6,7 +6,9 @@ import 'package:hypha_wallet/ui/profile/interactor/profile_data.dart'; class ProposalCreator extends StatelessWidget { final ProfileData? creator; - const ProposalCreator(this.creator, {super.key}); + final bool isColumn; + + const ProposalCreator(this.creator, {this.isColumn = true, super.key}); @override Widget build(BuildContext context) { @@ -19,20 +21,43 @@ class ProposalCreator extends StatelessWidget { ), const SizedBox(width: 10), Expanded( - child: Column( + child: isColumn + ? Column( crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - creator?.name ?? '', - style: context.hyphaTextTheme.reducedTitles, - ), - Text( - creator?.account ?? '', - style: context.hyphaTextTheme.ralMediumSmallNote.copyWith(color: HyphaColors.midGrey), ), - ], + children: children(context), + ) + : Row( + children: children(context), ), ), ], ); } + + List children(BuildContext context) { + return [ + Text( + creator?.name ?? '', + style: context.hyphaTextTheme.reducedTitles, + ), + if (!isColumn) ... [ + const SizedBox(width: 10), + Expanded( + child: text(context) + ), + ], + if(isColumn) + text(context) + ]; + } + + Widget text(BuildContext context){ + return Text( + creator?.account ?? '', + style: context.hyphaTextTheme.ralMediumSmallNote.copyWith( + color: isColumn ? HyphaColors.midGrey : HyphaColors.primaryBlu, + ), + overflow: TextOverflow.ellipsis, + ); + } } diff --git a/lib/ui/proposals/details/components/proposal_details_view.dart b/lib/ui/proposals/details/components/proposal_details_view.dart index 3d90f016..6500f4ab 100644 --- a/lib/ui/proposals/details/components/proposal_details_view.dart +++ b/lib/ui/proposals/details/components/proposal_details_view.dart @@ -1,14 +1,11 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; -import 'package:get/get.dart'; import 'package:hypha_wallet/core/extension/base_proposal_model_extension.dart'; -import 'package:hypha_wallet/core/extension/proposal_details_model_extension.dart'; import 'package:hypha_wallet/core/network/models/proposal_details_model.dart'; import 'package:hypha_wallet/core/network/models/vote_model.dart'; import 'package:hypha_wallet/design/background/hypha_page_background.dart'; import 'package:hypha_wallet/design/buttons/button_type.dart'; import 'package:hypha_wallet/design/buttons/hypha_app_button.dart'; -import 'package:hypha_wallet/design/dao_image.dart'; import 'package:hypha_wallet/design/dividers/hypha_divider.dart'; import 'package:hypha_wallet/design/hypha_colors.dart'; import 'package:hypha_wallet/design/themes/extensions/theme_extension_provider.dart'; @@ -30,7 +27,6 @@ class ProposalDetailsView extends StatefulWidget { } class _ProposalDetailsViewState extends State { - final ValueNotifier _isRewardShownPerCycle = ValueNotifier(false); final ValueNotifier _isOverflowingNotifier = ValueNotifier(false); final ValueNotifier _isExpandedNotifier = ValueNotifier(false); final ValueNotifier _detailsNotifier = ValueNotifier(null); @@ -72,18 +68,16 @@ class _ProposalDetailsViewState extends State { return HyphaBodyWidget( pageState: state.pageState, success: (context) { - final VoteModel? userVote = - _userVote(context, state.proposalDetailsModel!.votes); - final ProposalDetailsModel _proposalDetailsModel = - state.proposalDetailsModel!; - final List passVoters = _proposalDetailsModel - .fetchVotersByStatus(VoteStatus.pass); - final List failVoters = _proposalDetailsModel - .fetchVotersByStatus(VoteStatus.fail); + final VoteModel? userVote = _userVote(context, state.proposalDetailsModel!.votes); + final ProposalDetailsModel _proposalDetailsModel = state.proposalDetailsModel!; + final List passVoters = _proposalDetailsModel.fetchVotersByStatus(VoteStatus.pass); + final List failVoters = _proposalDetailsModel.fetchVotersByStatus(VoteStatus.fail); _detailsNotifier.value = _proposalDetailsModel.description; + WidgetsBinding.instance.addPostFrameCallback((_) { _checkIfTextIsOverflowing(); }); + return Padding( padding: const EdgeInsets.symmetric(horizontal: 30), child: ListView( @@ -93,176 +87,24 @@ class _ProposalDetailsViewState extends State { /// Header ProposalHeader(_proposalDetailsModel.dao), const Padding( - padding: EdgeInsets.only(top: 10, bottom: 20), + padding: EdgeInsets.symmetric(vertical: 20), child: HyphaDivider(), ), /// Main Section - Wrap( - children: List.generate( - _proposalDetailsModel.commitment != null ? 3 : 2, - (index) => Padding( - padding: const EdgeInsets.only(right: 10), - child: Container( - padding: const EdgeInsets.symmetric( - horizontal: 10, vertical: 4), - decoration: BoxDecoration( - border: Border.all( - color: context.isDarkMode - ? HyphaColors.white - : HyphaColors.lightBlack, - ), - borderRadius: BorderRadius.circular(20), - ), - // TODO(Zied-Saif): figure these out (B6 and Role) - child: Text( - index == 0 - ? 'Role ${_proposalDetailsModel.type}' - : index == 1 - ? 'B6' - : '${_proposalDetailsModel.commitment}%', - style: context.hyphaTextTheme.ralBold, - ), - ), - ), - ), - ), + ProposalCreator(_proposalDetailsModel.creator, isColumn: false), Padding( - padding: const EdgeInsets.symmetric(vertical: 20), + padding: const EdgeInsets.only(top: 30, bottom: 10), child: Text( - _proposalDetailsModel.title ?? 'No title', - style: context.hyphaTextTheme.mediumTitles, - ), - ), - ProposalCreator(_proposalDetailsModel.creator), - ...List.generate( - 2, - (index) => Padding( - padding: const EdgeInsets.only(top: 20), - child: ProposalPercentageIndicator( - index == 0 - ? 'Commitment' - : 'Token Mix Percentage', - index == 0 - ? _proposalDetailsModel - .commitmentToPercent() - : _proposalDetailsModel.tokenMixToPercent(), - HyphaColors.lightBlue), + 'Proposal Title', + style: context.hyphaTextTheme.ralMediumSmallNote.copyWith(color: HyphaColors.midGrey), ), ), - if (!(_proposalDetailsModel.cycleCount == null && - _proposalDetailsModel.cycleStartDate == null)) ...[ - const SizedBox(height: 20), - Text( - 'Duration', - style: context.hyphaTextTheme.ralMediumSmallNote - .copyWith(color: HyphaColors.midGrey), - ), - Padding( - padding: const EdgeInsets.symmetric(vertical: 10), - child: Text( - '${_proposalDetailsModel.cycleCount} Cycles', - style: context.hyphaTextTheme.reducedTitles, - ), - ), - ...List.generate( - 2, - (index) => Text( - index == 0 - ? 'Starting on ${_proposalDetailsModel.formatCycleStartDate()}' - : 'Ending on ${_proposalDetailsModel.cycleEndDate()}', - style: context.hyphaTextTheme.ralMediumBody - .copyWith(color: HyphaColors.midGrey), - ), - ), - ], - const Padding( - padding: EdgeInsets.symmetric(vertical: 20), - child: HyphaDivider(), + Text( + _proposalDetailsModel.title ?? 'No title', + style: context.hyphaTextTheme.mediumTitles, ), - - /// Rewards Section - if (_proposalDetailsModel.utilityAmount != null || - _proposalDetailsModel.utilityAmountPerPeriod != - null || - _proposalDetailsModel.voiceAmount != null || - _proposalDetailsModel.voiceAmountPerPeriod != - null || - _proposalDetailsModel.cashAmount != null || - _proposalDetailsModel.cashAmountPerPeriod != - null) ...[ - ValueListenableBuilder( - valueListenable: _isRewardShownPerCycle, - builder: (BuildContext context, bool isShown, - Widget? child) { - return Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - _isRewardShownPerCycle.value - ? 'Reward for one cycle' - : 'Reward for one period', - style: context - .hyphaTextTheme.ralMediumSmallNote - .copyWith(color: HyphaColors.midGrey), - ), - _buildTokenRow( - context, - _proposalDetailsModel, - 0, // Token index for Utility - TokenType.utility, - _isRewardShownPerCycle.value, - ), - _buildTokenRow( - context, - _proposalDetailsModel, - 1, // Token index for Voice - TokenType.voice, - _isRewardShownPerCycle.value, - ), - _buildTokenRow( - context, - _proposalDetailsModel, - 2, // Token index for Cash - TokenType.cash, - _isRewardShownPerCycle.value, - ), - const SizedBox(height: 10), - ], - ); - }, - ), - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Expanded( - child: Text( - 'Show rewards for 1 cycle', - style: context.hyphaTextTheme.ralMediumBody - .copyWith(color: HyphaColors.midGrey), - overflow: TextOverflow.ellipsis, - ), - ), - const SizedBox(width: 10), - ValueListenableBuilder( - valueListenable: _isRewardShownPerCycle, - builder: (BuildContext context, bool? value, - Widget? child) { - return Switch( - value: value!, - onChanged: (newValue) { - _isRewardShownPerCycle.value = newValue; - }, - ); - }, - ), - ], - ), - const Padding( - padding: EdgeInsets.symmetric(vertical: 20), - child: HyphaDivider(), - ), - ], + const SizedBox(height: 30), /// Details Section if (_proposalDetailsModel.description != null) ...[ @@ -473,63 +315,3 @@ Widget _buildVoteWidget(BuildContext context) => Column( ), ), ); - -Widget _buildTokenRow( - BuildContext context, - ProposalDetailsModel proposalDetailsModel, - int tokenIndex, - TokenType tokenType, - bool isRewardShownPerCycle) { - double? tokenAmount; - - // Determine the amount and amountPerPeriod based on token type - switch (tokenType) { - case TokenType.utility: - tokenAmount = proposalDetailsModel.tokenValue(0, isRewardShownPerCycle); - break; - case TokenType.voice: - tokenAmount = proposalDetailsModel.tokenValue(1, isRewardShownPerCycle); - break; - case TokenType.cash: - tokenAmount = proposalDetailsModel.tokenValue(2, isRewardShownPerCycle); - break; - } - - if (tokenAmount != null) { - return Padding( - padding: const EdgeInsets.only(top: 10), - child: Row( - children: [ - DaoImage(proposalDetailsModel.dao), - const SizedBox(width: 10), - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - proposalDetailsModel.tokenTitle(tokenIndex) ?? '', - style: context.hyphaTextTheme.reducedTitles, - overflow: TextOverflow.ellipsis, - ), - Text( - tokenType.name, - style: context.hyphaTextTheme.ralMediumBody - .copyWith(color: HyphaColors.midGrey), - overflow: TextOverflow.ellipsis, - ), - ], - ), - ), - const SizedBox(width: 10), - Text( - tokenAmount.toStringAsFixed(2), - style: context.hyphaTextTheme.bigTitles - .copyWith(fontWeight: FontWeight.normal), - ), - ], - ), - ); - } - - return const SizedBox.shrink(); -} diff --git a/lib/ui/proposals/list/interactor/proposals_bloc.dart b/lib/ui/proposals/list/interactor/proposals_bloc.dart index 8c33d538..feeb77ec 100644 --- a/lib/ui/proposals/list/interactor/proposals_bloc.dart +++ b/lib/ui/proposals/list/interactor/proposals_bloc.dart @@ -3,7 +3,6 @@ import 'package:freezed_annotation/freezed_annotation.dart'; import 'package:hypha_wallet/core/error_handler/error_handler_manager.dart'; import 'package:hypha_wallet/core/error_handler/model/hypha_error.dart'; import 'package:hypha_wallet/core/network/models/dao_data_model.dart'; -import 'package:hypha_wallet/core/network/models/dao_proposals_model.dart'; import 'package:hypha_wallet/core/network/models/proposal_model.dart'; import 'package:hypha_wallet/ui/architecture/interactor/page_states.dart'; import 'package:hypha_wallet/ui/architecture/result/result.dart'; diff --git a/lib/ui/proposals/list/usecases/get_proposals_use_case.dart b/lib/ui/proposals/list/usecases/get_proposals_use_case.dart index 07f59fb8..67f7e40b 100644 --- a/lib/ui/proposals/list/usecases/get_proposals_use_case.dart +++ b/lib/ui/proposals/list/usecases/get_proposals_use_case.dart @@ -6,8 +6,6 @@ import 'package:hypha_wallet/ui/architecture/interactor/base_usecase.dart'; import 'package:hypha_wallet/ui/architecture/result/result.dart'; import 'package:hypha_wallet/ui/proposals/list/interactor/get_proposals_use_case_input.dart'; -import '../../../../core/network/models/dao_proposals_model.dart'; - class GetProposalsUseCase extends InputUseCase, HyphaError>, GetProposalsUseCaseInput> { final AuthRepository _authRepository; final ProposalRepository _proposalRepository; @@ -16,5 +14,4 @@ class GetProposalsUseCase extends InputUseCase, Hypha @override Future, HyphaError>> run(GetProposalsUseCaseInput input) async => _proposalRepository.getProposals(_authRepository.authDataOrCrash.userProfileData, input); - Future, HyphaError>> run1(GetProposalsUseCaseInput input) async => _proposalRepository.getHistoryProposalsPerDao(_authRepository.authDataOrCrash.userProfileData, input); }