Skip to content

Commit

Permalink
feat: funded projects space (#794)
Browse files Browse the repository at this point in the history
* fix: jumping images in favorite proposals

* feat: add funded projects space
  • Loading branch information
dtscalac authored Sep 12, 2024
1 parent 1c71e1f commit 3cd05d0
Show file tree
Hide file tree
Showing 8 changed files with 243 additions and 16 deletions.
179 changes: 173 additions & 6 deletions catalyst_voices/lib/pages/funded_projects/funded_projects_page.dart
Original file line number Diff line number Diff line change
@@ -1,17 +1,184 @@
import 'package:catalyst_cardano_serialization/catalyst_cardano_serialization.dart';
import 'package:catalyst_voices/widgets/widgets.dart';
import 'package:catalyst_voices_assets/catalyst_voices_assets.dart';
import 'package:catalyst_voices_localization/catalyst_voices_localization.dart';
import 'package:catalyst_voices_models/catalyst_voices_models.dart';
import 'package:catalyst_voices_shared/catalyst_voices_shared.dart';
import 'package:flutter/material.dart';

final _proposalDescription = """
Zanzibar is becoming one of the hotspots for DID's through
World Mobile and PRISM, but its potential is only barely exploited.
Zanzibar is becoming one of the hotspots for DID's through World Mobile
and PRISM, but its potential is only barely exploited.
"""
.replaceAll('\n', ' ');

final _proposals = [
FundedProposal(
id: 'f14/0',
fund: 'F14',
category: 'Cardano Use Cases / MVP',
title: 'Proposal Title that rocks the world',
fundedDate: DateTime.now().minusDays(2),
fundsRequested: Coin.fromAda(100000),
commentsCount: 0,
description: _proposalDescription,
),
FundedProposal(
id: 'f14/1',
fund: 'F14',
category: 'Cardano Use Cases / MVP',
title: 'Proposal Title that rocks the world',
fundedDate: DateTime.now().minusDays(2),
fundsRequested: Coin.fromAda(100000),
commentsCount: 0,
description: _proposalDescription,
),
FundedProposal(
id: 'f14/2',
fund: 'F14',
category: 'Cardano Use Cases / MVP',
title: 'Proposal Title that rocks the world',
fundedDate: DateTime.now().minusDays(2),
fundsRequested: Coin.fromAda(100000),
commentsCount: 0,
description: _proposalDescription,
),
];

final _proposalImages = {
for (final (index, proposal) in _proposals.indexed)
proposal.id: index.isEven
? VoicesAssets.images.proposalBackground1
: VoicesAssets.images.proposalBackground2,
};

final _favoriteProposals = ValueNotifier<List<FundedProposal>>([]);

class FundedProjectsPage extends StatelessWidget {
const FundedProjectsPage({super.key});

@override
Widget build(BuildContext context) {
return Container(
color: Colors.deepOrangeAccent,
alignment: Alignment.center,
child: Text(
'Funded Projects',
style: Theme.of(context).textTheme.titleLarge,
return ListView(
padding: const EdgeInsets.symmetric(horizontal: 32),
children: [
const SizedBox(height: 44),
Text(
context.l10n.fundedProjectSpace,
style: Theme.of(context).textTheme.headlineLarge,
),
const SizedBox(height: 44),
_Tabs(),
],
);
}
}

class _Tabs extends StatelessWidget {
const _Tabs();

@override
Widget build(BuildContext context) {
return DefaultTabController(
length: 2,
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
TabBar(
isScrollable: true,
tabAlignment: TabAlignment.start,
tabs: [
Tab(
text: context.l10n.noOfFundedProposals(_proposals.length),
),
Tab(
child: Row(
children: [
Icon(CatalystVoicesIcons.plus_circle),
const SizedBox(width: 8),
Text(context.l10n.followed),
],
),
),
],
),
const SizedBox(height: 24),
TabBarStackView(
children: [
_AllProposals(),
_FavoriteProposals(),
],
),
const SizedBox(height: 12),
],
),
);
}
}

class _AllProposals extends StatelessWidget {
const _AllProposals();

@override
Widget build(BuildContext context) {
return ValueListenableBuilder<List<FundedProposal>>(
valueListenable: _favoriteProposals,
builder: (context, favoriteProposals, child) {
return Wrap(
spacing: 16,
runSpacing: 16,
children: [
for (final proposal in _proposals)
FundedProposalCard(
image: _proposalImages[proposal.id]!,
proposal: proposal,
isFavorite: favoriteProposals.contains(proposal),
onFavoriteChanged: (isFavorite) =>
_onFavoriteChanged(proposal, isFavorite),
),
],
);
},
);
}
}

class _FavoriteProposals extends StatelessWidget {
const _FavoriteProposals();

@override
Widget build(BuildContext context) {
return ValueListenableBuilder<List<FundedProposal>>(
valueListenable: _favoriteProposals,
builder: (context, favoriteProposals, child) {
return Wrap(
spacing: 16,
runSpacing: 16,
children: [
for (final proposal in favoriteProposals)
FundedProposalCard(
image: _proposalImages[proposal.id]!,
proposal: proposal,
isFavorite: true,
onFavoriteChanged: (isFavorite) =>
_onFavoriteChanged(proposal, isFavorite),
),
],
);
},
);
}
}

void _onFavoriteChanged(FundedProposal proposal, bool isFavorite) {
final proposals = Set.of(_favoriteProposals.value);
if (isFavorite) {
proposals.add(proposal);
} else {
proposals.remove(proposal);
}
_favoriteProposals.value = proposals.toList();
}
19 changes: 11 additions & 8 deletions catalyst_voices/lib/pages/voting/voting_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,13 @@ final _proposals = [
),
];

final _proposalImages = {
for (final (index, proposal) in _proposals.indexed)
proposal.id: index.isEven
? VoicesAssets.images.proposalBackground1
: VoicesAssets.images.proposalBackground2,
};

final _favoriteProposals = ValueNotifier<List<PendingProposal>>([]);

class VotingPage extends StatelessWidget {
Expand Down Expand Up @@ -131,11 +138,9 @@ class _AllProposals extends StatelessWidget {
spacing: 16,
runSpacing: 16,
children: [
for (final (index, proposal) in _proposals.indexed)
for (final proposal in _proposals)
PendingProposalCard(
image: index.isEven
? VoicesAssets.images.proposalBackground1
: VoicesAssets.images.proposalBackground2,
image: _proposalImages[proposal.id]!,
proposal: proposal,
isFavorite: favoriteProposals.contains(proposal),
onFavoriteChanged: (isFavorite) =>
Expand All @@ -160,11 +165,9 @@ class _FavoriteProposals extends StatelessWidget {
spacing: 16,
runSpacing: 16,
children: [
for (final (index, proposal) in favoriteProposals.indexed)
for (final proposal in favoriteProposals)
PendingProposalCard(
image: index.isEven
? VoicesAssets.images.proposalBackground1
: VoicesAssets.images.proposalBackground2,
image: _proposalImages[proposal.id]!,
proposal: proposal,
isFavorite: true,
onFavoriteChanged: (isFavorite) =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ class _Header extends StatelessWidget {
padding: EdgeInsets.zero,
onPressed: () => onFavoriteChanged?.call(!isFavorite),
icon: Icon(
isFavorite ? Icons.favorite : CatalystVoicesIcons.star,
isFavorite ? Icons.favorite : CatalystVoicesIcons.plus_circle,
size: 20,
color: Theme.of(context).colors.iconsOnImage,
),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ const VoicesColorScheme lightVoicesColorScheme = VoicesColorScheme(
onSurfaceError08: VoicesColors.lightOnSurfaceError08,
onSurfaceError012: VoicesColors.lightOnSurfaceError012,
onSurfaceError016: VoicesColors.lightOnSurfaceError016,
iconsForeground: Color.fromARGB(255, 151, 164, 193),
iconsForeground: VoicesColors.lightIconsForeground,
iconsBackground: VoicesColors.lightIconsBackground,
iconsOnImage: VoicesColors.lightIconsOnImage,
iconsDisabled: VoicesColors.lightIconsDisabled,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -477,6 +477,24 @@ abstract class VoicesLocalizations {
/// In en, this message translates to:
/// **'Funded projects'**
String get drawerSpaceFundedProjects;

/// Title of the funded project space
///
/// In en, this message translates to:
/// **'Funded project space'**
String get fundedProjectSpace;

/// Tab label for funded proposals in funded projects space
///
/// In en, this message translates to:
/// **'Funded proposals ({count})'**
String noOfFundedProposals(int count);

/// Refers to a list of followed items.
///
/// In en, this message translates to:
/// **'Followed'**
String get followed;
}

class _VoicesLocalizationsDelegate extends LocalizationsDelegate<VoicesLocalizations> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -250,4 +250,15 @@ class VoicesLocalizationsEn extends VoicesLocalizations {

@override
String get drawerSpaceFundedProjects => 'Funded projects';

@override
String get fundedProjectSpace => 'Funded project space';

@override
String noOfFundedProposals(int count) {
return 'Funded proposals ($count)';
}

@override
String get followed => 'Followed';
}
Original file line number Diff line number Diff line change
Expand Up @@ -250,4 +250,15 @@ class VoicesLocalizationsEs extends VoicesLocalizations {

@override
String get drawerSpaceFundedProjects => 'Funded projects';

@override
String get fundedProjectSpace => 'Funded project space';

@override
String noOfFundedProposals(int count) {
return 'Funded proposals ($count)';
}

@override
String get followed => 'Followed';
}
Original file line number Diff line number Diff line change
Expand Up @@ -296,5 +296,22 @@
"drawerSpaceFundedProjects": "Funded projects",
"@drawerSpaceFundedProjects": {
"description": "Name shown in spaces shell drawer"
},
"fundedProjectSpace": "Funded project space",
"@fundedProjectSpace": {
"description": "Title of the funded project space"
},
"noOfFundedProposals": "Funded proposals ({count})",
"@noOfFundedProposals": {
"description": "Tab label for funded proposals in funded projects space",
"placeholders": {
"count": {
"type": "int"
}
}
},
"followed": "Followed",
"@followed": {
"description": "Refers to a list of followed items."
}
}

0 comments on commit 3cd05d0

Please sign in to comment.