Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: funded proposal card #772

Merged
merged 6 commits into from
Sep 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .config/dictionaries/project.dic
Original file line number Diff line number Diff line change
Expand Up @@ -252,3 +252,5 @@ interps
todos
vsync
damian-molinski
LTRB
hotspots
233 changes: 233 additions & 0 deletions catalyst_voices/lib/widgets/cards/funded_proposal_card.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,233 @@
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_brands/catalyst_voices_brands.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';

/// Displays a proposal in funded state on a card.
class FundedProposalCard extends StatelessWidget {
final AssetGenImage image;
final FundedProposal proposal;

const FundedProposalCard({
super.key,
required this.image,
required this.proposal,
});

@override
Widget build(BuildContext context) {
return Container(
width: 326,
clipBehavior: Clip.antiAlias,
decoration: BoxDecoration(
color: Theme.of(context).colorScheme.surface,
borderRadius: BorderRadius.circular(12),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
_Header(image: image),
Padding(
padding: const EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
_FundCategory(
fund: proposal.fund,
category: proposal.category,
),
const SizedBox(height: 4),
_Title(text: proposal.title),
const SizedBox(height: 4),
_FundedDate(dateTime: proposal.fundedDate),
const SizedBox(height: 24),
_FundsAndComments(
funds: proposal.fundsRequested,
commentsCount: proposal.commentsCount,
),
const SizedBox(height: 24),
_Description(text: proposal.description),
],
),
),
],
),
);
}
}

class _Header extends StatelessWidget {
final AssetGenImage image;

const _Header({required this.image});

@override
Widget build(BuildContext context) {
return SizedBox(
height: 168,
child: Stack(
children: [
Positioned.fill(
child: CatalystImage.asset(
image.path,
fit: BoxFit.cover,
),
),
Positioned(
top: 2,
right: 2,
child: IconButton(
padding: EdgeInsets.zero,
onPressed: () {},
icon: Icon(
CatalystVoicesIcons.plus_circle,
size: 20,
color: Theme.of(context).colors.iconsOnImage,
),
),
),
Positioned(
left: 12,
bottom: 12,
child: VoicesChip.rectangular(
padding: const EdgeInsets.fromLTRB(10, 6, 10, 4),
leading: Icon(
CatalystVoicesIcons.briefcase,
color: Theme.of(context).colorScheme.primary,
),
content: Text(context.l10n.fundedProposal),
backgroundColor: Theme.of(context).colors.primary98,
),
),
],
),
);
}
}

class _FundCategory extends StatelessWidget {
final String fund;
final String category;

const _FundCategory({
required this.fund,
required this.category,
});

@override
Widget build(BuildContext context) {
return Text.rich(
TextSpan(
text: fund + ' / ',
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
color: Theme.of(context).colors.textDisabled,
),
children: [
TextSpan(
text: category,
style: Theme.of(context).textTheme.bodyMedium,
),
],
),
);
}
}

class _Title extends StatelessWidget {
final String text;

const _Title({required this.text});

@override
Widget build(BuildContext context) {
return Text(
text,
style: Theme.of(context).textTheme.titleLarge,
maxLines: 2,
overflow: TextOverflow.ellipsis,
);
}
}

class _FundedDate extends StatelessWidget {
final DateTime dateTime;

const _FundedDate({required this.dateTime});

@override
Widget build(BuildContext context) {
return Text(
context.l10n.fundedProposalDate(dateTime),
style: Theme.of(context).textTheme.bodySmall,
);
}
}

class _FundsAndComments extends StatelessWidget {
final Coin funds;
final int commentsCount;

const _FundsAndComments({
required this.funds,
required this.commentsCount,
});

@override
Widget build(BuildContext context) {
return Container(
padding: EdgeInsets.symmetric(horizontal: 16, vertical: 6),
decoration: BoxDecoration(
color: Theme.of(context).colors.success?.withOpacity(0.08),
borderRadius: BorderRadius.circular(8),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Column(
children: [
Text(
CryptocurrencyFormatter.formatAmount(funds),
style: Theme.of(context).textTheme.titleLarge,
),
Text(
context.l10n.fundsRequested,
style: Theme.of(context).textTheme.bodySmall,
),
],
),
VoicesChip.rectangular(
padding: const EdgeInsets.fromLTRB(8, 6, 12, 6),
leading: Icon(
CatalystVoicesIcons.check_circle,
color: Theme.of(context).colors.success,
),
content: Text(context.l10n.noOfComments(commentsCount)),
backgroundColor: Theme.of(context).colors.successContainer,
),
],
),
);
}
}

class _Description extends StatelessWidget {
final String text;

const _Description({required this.text});

@override
Widget build(BuildContext context) {
return Text(
text,
style: Theme.of(context).textTheme.bodyLarge?.copyWith(
color: Theme.of(context).colors.textOnPrimary,
),
maxLines: 4,
overflow: TextOverflow.ellipsis,
);
}
}
1 change: 1 addition & 0 deletions catalyst_voices/lib/widgets/widgets.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ export 'buttons/voices_icon_button.dart';
export 'buttons/voices_outlined_button.dart';
export 'buttons/voices_segmented_button.dart';
export 'buttons/voices_text_button.dart';
export 'cards/funded_proposal_card.dart';
export 'chips/voices_chip.dart';
export 'common/link_text.dart';
export 'common/navigation_location.dart';
Expand Down
14 changes: 14 additions & 0 deletions catalyst_voices/macos/Flutter/GeneratedPluginRegistrant.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,30 @@
import FlutterMacOS
import Foundation

import device_info_plus
import file_selector_macos
import flutter_inappwebview_macos
import flutter_secure_storage_macos
import gal
import irondash_engine_context
import package_info_plus
import path_provider_foundation
import sentry_flutter
import super_native_extensions
import url_launcher_macos
import video_player_avfoundation

func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
DeviceInfoPlusMacosPlugin.register(with: registry.registrar(forPlugin: "DeviceInfoPlusMacosPlugin"))
FileSelectorPlugin.register(with: registry.registrar(forPlugin: "FileSelectorPlugin"))
InAppWebViewFlutterPlugin.register(with: registry.registrar(forPlugin: "InAppWebViewFlutterPlugin"))
FlutterSecureStoragePlugin.register(with: registry.registrar(forPlugin: "FlutterSecureStoragePlugin"))
GalPlugin.register(with: registry.registrar(forPlugin: "GalPlugin"))
IrondashEngineContextPlugin.register(with: registry.registrar(forPlugin: "IrondashEngineContextPlugin"))
FPPPackageInfoPlusPlugin.register(with: registry.registrar(forPlugin: "FPPPackageInfoPlusPlugin"))
PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))
SentryFlutterPlugin.register(with: registry.registrar(forPlugin: "SentryFlutterPlugin"))
SuperNativeExtensionsPlugin.register(with: registry.registrar(forPlugin: "SuperNativeExtensionsPlugin"))
UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin"))
FVPVideoPlayerPlugin.register(with: registry.registrar(forPlugin: "FVPVideoPlayerPlugin"))
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
<color name="light_text_on_primary_container">#FFFFFF</color>
<color name="light_text_disabled">#61212A3D</color>
<color name="light_primary">#123CD3</color>
<color name="light_primary_98">#E8ECFD</color>
<color name="light_on_primary">#FFFFFF</color>
<color name="light_primary_container">#A1B4F7</color>
<color name="light_on_primary_container">#081B5E</color>
Expand Down Expand Up @@ -44,6 +45,7 @@
<color name="light_on_surface_error_016">#29CC0000</color>
<color name="light_icons_foreground">#212A3D</color>
<color name="light_icons_background">#FFFFFF</color>
<color name="light_icons_on_image">#FFFFFF</color>
<color name="light_icons_disabled">#61212A3D</color>
<color name="light_icons_primary">#123CD3</color>
<color name="light_icons_secondary">#C014EB</color>
Expand All @@ -66,6 +68,7 @@
<color name="dark_text_on_primary_container">#0C288D</color>
<color name="dark_text_disabled">#61D9DEE8</color>
<color name="dark_primary">#728EF3</color>
<color name="dark_primary_98">#364463</color>
<color name="dark_on_primary">#0C288D</color>
<color name="dark_primary_container">#1035BC</color>
<color name="dark_on_primary_container">#E8ECFD</color>
Expand Down Expand Up @@ -105,6 +108,7 @@
<color name="dark_on_surface_error_016">#29CC0000</color>
<color name="dark_icons_foreground">#F2F4F8</color>
<color name="dark_icons_background">#212A3D</color>
<color name="dark_icons_on_image">#FFFFFF</color>
<color name="dark_icons_disabled">#61BFC8D9</color>
<color name="dark_icons_primary">#728EF3</color>
<color name="dark_icons_secondary">#DF8AF5</color>
Expand Down
Binary file not shown.
Binary file not shown.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading