Skip to content

Commit

Permalink
Merge pull request #316 from hypha-dao/feat/implement-filter-proposal…
Browse files Browse the repository at this point in the history
…s-logic

feat: implement filter proposals logic
  • Loading branch information
Zied-Dahmani authored Sep 23, 2024
2 parents 4a4cab5 + 1297996 commit 095ac10
Show file tree
Hide file tree
Showing 30 changed files with 1,401 additions and 222 deletions.
10 changes: 9 additions & 1 deletion lib/core/di/bloc_module.dart
Original file line number Diff line number Diff line change
Expand Up @@ -134,9 +134,17 @@ void _registerBlocsModule() {
_getIt<AuthRepository>(),
));

_registerFactory(() => ProposalsBloc(
_registerLazySingleton(() => ProposalsBloc(
_getIt<GetProposalsUseCase>(),
_getIt<FetchProfileUseCase>(),
_getIt<ErrorHandlerManager>(),
));

_registerLazySingleton(() => FilterProposalsBloc(
_getIt<ProposalsBloc>(),
_getIt<FetchProfileUseCase>(),
_getIt<AggregateDaoProposalCountsUseCase>(),
_getIt<GetDaosFromProposalCountsUseCase>(),
_getIt<ErrorHandlerManager>(),
));
}
3 changes: 3 additions & 0 deletions lib/core/di/di_setup.dart
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,9 @@ import 'package:hypha_wallet/ui/profile/usecases/set_bio_use_case.dart';
import 'package:hypha_wallet/ui/profile/usecases/set_image_use_case.dart';
import 'package:hypha_wallet/ui/profile/usecases/set_name_use_case.dart';
import 'package:hypha_wallet/ui/proposals/details/usecases/get_proposal_details_use_case.dart';
import 'package:hypha_wallet/ui/proposals/filter/interactor/filter_proposals_bloc.dart';
import 'package:hypha_wallet/ui/proposals/filter/usecases/aggregate_dao_proposal_counts_use_case.dart';
import 'package:hypha_wallet/ui/proposals/filter/usecases/get_daos_from_proposal_counts_use_case.dart';
import 'package:hypha_wallet/ui/proposals/list/interactor/proposals_bloc.dart';
import 'package:hypha_wallet/ui/proposals/list/usecases/get_proposals_use_case.dart';
import 'package:hypha_wallet/ui/search_user/interactor/search_user_bloc.dart';
Expand Down
4 changes: 4 additions & 0 deletions lib/core/di/usecases_module.dart
Original file line number Diff line number Diff line change
Expand Up @@ -86,4 +86,8 @@ void _registerUseCasesModule() {
_registerFactory(() => GetProposalsUseCase(_getIt<AuthRepository>(), _getIt<ProposalRepository>()));

_registerFactory(() => GetProposalDetailsUseCase(_getIt<AuthRepository>(), _getIt<ProposalRepository>()));

_registerFactory(() => AggregateDaoProposalCountsUseCase());

_registerFactory(() => GetDaosFromProposalCountsUseCase());
}
11 changes: 9 additions & 2 deletions lib/core/network/api/services/proposal_service.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,18 @@ class ProposalService {

const ProposalService(this._graphQLService);

Future<Result<Map<String, dynamic>, HyphaError>> getProposals(UserProfileData user, int daoId) async {
final String query = '{"query":"query Proposals(\$docId: String!) { queryDao(filter: { docId: { eq: \$docId } }) { proposal { docId ... on Poll { details_title_s details_ballotAlignment_i details_ballotQuorum_i ballot_expiration_t creator } ... on Budget { details_title_s details_ballotAlignment_i details_ballotQuorum_i ballot_expiration_t creator } ... on Queststart { details_title_s details_ballotAlignment_i details_ballotQuorum_i ballot_expiration_t creator } ... on Questcomplet { details_title_s details_ballotAlignment_i details_ballotQuorum_i ballot_expiration_t creator } ... on Policy { details_title_s details_ballotAlignment_i details_ballotQuorum_i ballot_expiration_t creator } ... on Circle { details_title_s details_ballotAlignment_i details_ballotQuorum_i ballot_expiration_t creator } ... on Payout { details_title_s details_ballotAlignment_i details_ballotQuorum_i ballot_expiration_t creator } ... on Assignment { details_timeShareX100_i details_title_s details_ballotAlignment_i details_ballotQuorum_i ballot_expiration_t creator } ... on Assignbadge { details_title_s details_ballotAlignment_i details_ballotQuorum_i ballot_expiration_t creator } ... on Role { details_title_s details_ballotAlignment_i details_ballotQuorum_i ballot_expiration_t creator } ... on Badge { details_title_s details_ballotAlignment_i details_ballotQuorum_i ballot_expiration_t creator } ... on Suspend { details_title_s details_ballotAlignment_i details_ballotQuorum_i ballot_expiration_t creator } ... on Edit { details_timeShareX100_i original { ... on Assignbadge { details_title_s } ... on Assignment { details_title_s } } details_ballotAlignment_i details_ballotQuorum_i ballot_expiration_t creator } ... on Votable { vote { ... on Vote { vote_voter_n vote_vote_s } } } } } }","variables":{"docId":"$daoId"}}';
Future<Result<Map<String, dynamic>, HyphaError>> getActiveProposals(UserProfileData user, int daoId) async {
final String query = '{"query":"query ActiveProposals(\$docId: String!) { queryDao(filter: { docId: { eq: \$docId } }) { proposal { docId ... on Poll { details_title_s details_ballotAlignment_i details_ballotQuorum_i ballot_expiration_t creator } ... on Budget { details_title_s details_ballotAlignment_i details_ballotQuorum_i ballot_expiration_t creator } ... on Queststart { details_title_s details_ballotAlignment_i details_ballotQuorum_i ballot_expiration_t creator } ... on Questcomplet { details_title_s details_ballotAlignment_i details_ballotQuorum_i ballot_expiration_t creator } ... on Policy { details_title_s details_ballotAlignment_i details_ballotQuorum_i ballot_expiration_t creator } ... on Circle { details_title_s details_ballotAlignment_i details_ballotQuorum_i ballot_expiration_t creator } ... on Payout { details_title_s details_ballotAlignment_i details_ballotQuorum_i ballot_expiration_t creator } ... on Assignment { details_timeShareX100_i details_title_s details_ballotAlignment_i details_ballotQuorum_i ballot_expiration_t creator } ... on Assignbadge { details_title_s details_ballotAlignment_i details_ballotQuorum_i ballot_expiration_t creator } ... on Role { details_title_s details_ballotAlignment_i details_ballotQuorum_i ballot_expiration_t creator } ... on Badge { details_title_s details_ballotAlignment_i details_ballotQuorum_i ballot_expiration_t creator } ... on Suspend { details_title_s details_ballotAlignment_i details_ballotQuorum_i ballot_expiration_t creator } ... on Edit { details_timeShareX100_i original { ... on Assignbadge { details_title_s } ... on Assignment { details_title_s } } details_ballotAlignment_i details_ballotQuorum_i ballot_expiration_t creator } ... on Votable { vote { ... on Vote { vote_voter_n vote_vote_s } } } } } }","variables":{"docId":"$daoId"}}';

return _graphQLService.graphQLQuery(network: user.network, query: query);
}

Future<Result<Map<String, dynamic>, HyphaError>> getPastProposals(UserProfileData user, int daoId) async {
final String query = '{"query":"query PastProposals(\$docId: String!) { queryDao(filter: { docId: { eq: \$docId } }) { votable { docId ... on Poll { details_title_s details_ballotAlignment_i details_ballotQuorum_i ballot_expiration_t creator } ... on Budget { details_title_s details_ballotAlignment_i details_ballotQuorum_i ballot_expiration_t creator } ... on Queststart { details_title_s details_ballotAlignment_i details_ballotQuorum_i ballot_expiration_t creator } ... on Questcomplet { details_title_s details_ballotAlignment_i details_ballotQuorum_i ballot_expiration_t creator } ... on Policy { details_title_s details_ballotAlignment_i details_ballotQuorum_i ballot_expiration_t creator } ... on Circle { details_title_s details_ballotAlignment_i details_ballotQuorum_i ballot_expiration_t creator } ... on Payout { details_title_s details_ballotAlignment_i details_ballotQuorum_i ballot_expiration_t creator } ... on Assignment { details_timeShareX100_i details_title_s details_ballotAlignment_i details_ballotQuorum_i ballot_expiration_t creator } ... on Assignbadge { details_title_s details_ballotAlignment_i details_ballotQuorum_i ballot_expiration_t creator } ... on Role { details_title_s details_ballotAlignment_i details_ballotQuorum_i ballot_expiration_t creator } ... on Badge { details_title_s details_ballotAlignment_i details_ballotQuorum_i ballot_expiration_t creator } ... on Suspend { details_title_s details_ballotAlignment_i details_ballotQuorum_i ballot_expiration_t creator } ... on Edit { details_timeShareX100_i original { ... on Assignbadge { details_title_s } ... on Assignment { details_title_s } } details_ballotAlignment_i details_ballotQuorum_i ballot_expiration_t creator } ... on Votable { vote { ... on Vote { vote_voter_n vote_vote_s } } } } } }","variables":{"docId":"$daoId"}}';

return _graphQLService.graphQLQuery(network: user.network, query: query);
}

Future<Result<Map<String, dynamic>, HyphaError>> getProposalDetails(
String proposalId, UserProfileData user) async {
final String query =
Expand Down
16 changes: 14 additions & 2 deletions lib/core/network/models/dao_data_model.dart
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
class DaoData {
import 'package:equatable/equatable.dart';

class DaoData extends Equatable{
final int docId;
final String detailsDaoName;
final String settingsDaoTitle;
final String logoIPFSHash;
final String logoType;
final String settingsDaoUrl;

DaoData({
const DaoData({
required this.docId,
required this.detailsDaoName,
required this.settingsDaoTitle,
Expand All @@ -15,6 +17,16 @@ class DaoData {
required this.settingsDaoUrl,
});

@override
List<Object?> get props => [
docId,
detailsDaoName,
settingsDaoTitle,
logoIPFSHash,
logoType,
settingsDaoUrl,
];

factory DaoData.fromJson(Map<String, dynamic> json) {
final Map<String, dynamic> settings = json['settings'][0];
print('got settings result: $settings');
Expand Down
13 changes: 7 additions & 6 deletions lib/core/network/repository/proposal_repository.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,17 @@ import 'package:hypha_wallet/core/network/models/user_profile_data.dart';
import 'package:hypha_wallet/core/network/repository/profile_repository.dart';
import 'package:hypha_wallet/ui/architecture/result/result.dart';
import 'package:hypha_wallet/ui/profile/interactor/profile_data.dart';
import 'package:hypha_wallet/ui/proposals/filter/interactor/filter_status.dart';

class ProposalRepository {
final ProposalService _proposalService;
final ProfileService _profileService;

ProposalRepository(this._proposalService, this._profileService);

Future<Result<List<ProposalModel>, HyphaError>> getProposals(UserProfileData user, List<DaoData> daos) async {
final List<Future<Result<Map<String, dynamic>, HyphaError>>> futures = daos.map((dao) {
return _proposalService.getProposals(user, dao.docId);
Future<Result<List<ProposalModel>, HyphaError>> getProposals(UserProfileData user, List<DaoData> daos, FilterStatus filterStatus) async {
final List<Future<Result<Map<String, dynamic>, HyphaError>>> futures = daos.map((DaoData dao) {
return filterStatus == FilterStatus.active ? _proposalService.getActiveProposals(user, dao.docId) : _proposalService.getPastProposals(user, dao.docId);
}).toList();

final List<Result<Map<String, dynamic>, HyphaError>> futureResults = await Future.wait(futures);
Expand All @@ -37,7 +38,7 @@ class ProposalRepository {
}

try {
final List<ProposalModel> proposals = await _parseProposalsFromResponse(response, daos[i]);
final List<ProposalModel> proposals = await _parseProposalsFromResponse(response, daos[i], filterStatus);
allProposals.addAll(proposals);
} catch (e, stackTrace) {
LogHelper.e('Error parsing data into proposal model', error: e, stacktrace: stackTrace);
Expand All @@ -53,11 +54,11 @@ class ProposalRepository {
return Result.value(allProposals);
}

Future<List<ProposalModel>> _parseProposalsFromResponse(Map<String, dynamic> response, DaoData daoData) async {
Future<List<ProposalModel>> _parseProposalsFromResponse(Map<String, dynamic> response, DaoData daoData, FilterStatus filterStatus) async {
final List<dynamic> proposalsData = response['data']['queryDao'];

final List<Future<ProposalModel>> proposalFutures = proposalsData.expand((dao) {
final List<dynamic> proposals = dao['proposal'] as List<dynamic>;
final List<dynamic> proposals = dao[filterStatus == FilterStatus.active ? 'proposal' : 'votable'] as List<dynamic>;
return proposals.map((dynamic proposal) async {
final Result<ProfileData, HyphaError> creator = await _profileService.getProfile(proposal['creator']);
proposal['creator'] = null;
Expand Down
26 changes: 26 additions & 0 deletions lib/design/dao_image.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import 'package:flutter/material.dart';
import 'package:hypha_wallet/core/network/models/dao_data_model.dart';
import 'package:hypha_wallet/design/ipfs_image.dart';

class DaoImage extends StatelessWidget {
final DaoData? dao;
const DaoImage(this.dao, {super.key});

@override
Widget build(BuildContext context) {
return Container(
width: 48,
height: 48,
decoration: const BoxDecoration(
shape: BoxShape.circle,
color: Colors.white,
),
child: ClipOval(
child: IpfsImage(
ipfsHash: dao?.logoIPFSHash ?? '',
type: dao?.logoType ?? '',
),
),
);
}
}
17 changes: 2 additions & 15 deletions lib/ui/profile/components/dao_widget.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import 'package:hypha_wallet/design/hypha_card.dart';
import 'package:hypha_wallet/design/hypha_colors.dart';
import 'package:hypha_wallet/design/ipfs_image.dart';
import 'package:hypha_wallet/design/themes/extensions/theme_extension_provider.dart';
import 'package:hypha_wallet/design/dao_image.dart';
import 'package:url_launcher/url_launcher.dart';

class DaoWidget extends StatelessWidget {
Expand Down Expand Up @@ -43,21 +44,7 @@ class DaoWidget extends StatelessWidget {
Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Container(
width: 48,
height: 48,
decoration: const BoxDecoration(
shape: BoxShape.circle,
color:
Colors.white, // Note: white bg is standard on the DAO website where people upload images
),
child: ClipOval(
child: IpfsImage(
ipfsHash: dao.logoIPFSHash,
type: dao.logoType,
),
),
),
DaoImage(dao),
const SizedBox(width: 8),
Expanded(
child: Column(
Expand Down
24 changes: 5 additions & 19 deletions lib/ui/proposals/components/proposal_header.dart
Original file line number Diff line number Diff line change
@@ -1,35 +1,21 @@
import 'package:flutter/material.dart';
import 'package:hypha_wallet/core/network/models/dao_data_model.dart';
import 'package:hypha_wallet/design/ipfs_image.dart';
import 'package:hypha_wallet/design/dao_image.dart';
import 'package:hypha_wallet/design/themes/extensions/theme_extension_provider.dart';

class ProposalHeader extends StatelessWidget {
final DaoData? _daoData;
const ProposalHeader(this._daoData, {super.key});
final DaoData? _dao;
const ProposalHeader(this._dao, {super.key});

@override
Widget build(BuildContext context) {
return Row(
children: [
Container(
width: 48,
height: 48,
decoration: const BoxDecoration(
shape: BoxShape.circle,
color:
Colors.white,
),
child: ClipOval(
child: IpfsImage(
ipfsHash: _daoData?.logoIPFSHash ?? '',
type: _daoData?.logoType ?? '',
),
),
),
DaoImage(_dao),
const SizedBox(width: 10),
Flexible(
child: Text(
_daoData?.settingsDaoTitle ?? '',
_dao?.settingsDaoTitle ?? '',
style: context.hyphaTextTheme.ralMediumSmallNote.copyWith(fontWeight: FontWeight.bold),
overflow: TextOverflow.ellipsis,
),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import 'package:hypha_wallet/design/avatar_image/hypha_avatar_image.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';
Expand Down Expand Up @@ -158,8 +159,7 @@ class _ProposalDetailsViewState extends State<ProposalDetailsView> {
child: HyphaDivider(),
),
/// Rewards Section
// TODO(Zied): implement the logic
if (!(_proposalDetailsModel.utilityAmount == null && _proposalDetailsModel.utilityAmountPerPeriod == null)) ... [
if (_proposalDetailsModel.utilityAmount != null || _proposalDetailsModel.utilityAmountPerPeriod != null) ... [
ValueListenableBuilder<bool?>(
valueListenable: _isShownNotifier,
builder: (BuildContext context, bool? isShown, Widget? child) {
Expand All @@ -176,10 +176,7 @@ class _ProposalDetailsViewState extends State<ProposalDetailsView> {
padding: const EdgeInsets.only(top: 10),
child: Row(
children: [
const HyphaAvatarImage(
imageRadius: 24,
imageFromUrl: 'https://etudestech.com/wp-content/uploads/2023/05/midjourney-scaled.jpeg',
),
DaoImage(_proposalDetailsModel.dao),
const SizedBox(width: 10),
Expanded(
child: Column(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import 'package:hypha_wallet/core/error_handler/model/hypha_error.dart';
import 'package:hypha_wallet/core/network/models/proposal_details_model.dart';
import 'package:hypha_wallet/core/network/models/proposal_model.dart';
import 'package:hypha_wallet/core/network/repository/auth_repository.dart';
import 'package:hypha_wallet/core/network/repository/proposal_repository.dart';
import 'package:hypha_wallet/ui/architecture/result/result.dart';
Expand Down
Loading

0 comments on commit 095ac10

Please sign in to comment.