From 1e076c79692d1177bbb590da2a17ec730ec5287c Mon Sep 17 00:00:00 2001 From: AhsanRns Date: Wed, 8 May 2024 11:03:27 +0500 Subject: [PATCH] feat: Event provide, price text input field --- evently/assets/images/denom_pylon.png | Bin 0 -> 804 bytes evently/assets/images/denom_usd.png | Bin 0 -> 1169 bytes evently/assets/images/text_field_button.png | Bin 0 -> 370 bytes evently/i18n/de.json | 7 +- evently/i18n/en-US.json | 7 +- evently/i18n/es.json | 7 +- evently/i18n/ru-RU.json | 7 +- evently/lib/evently_provider.dart | 26 ++ evently/lib/generated/locale_keys.g.dart | 5 + evently/lib/models/denom.dart | 84 ++++++ evently/lib/screens/detail_screen.dart | 2 +- evently/lib/screens/overview_screen.dart | 2 +- evently/lib/screens/perks_screen.dart | 2 +- evently/lib/screens/price_screen.dart | 249 +++++++++++++++++- evently/lib/utils/amount_formatter.dart | 28 ++ evently/lib/utils/constants.dart | 24 ++ .../widgets/evently_price_input_field.dart | 113 ++++++++ ...ext_field.dart => evently_text_field.dart} | 0 18 files changed, 554 insertions(+), 9 deletions(-) create mode 100644 evently/assets/images/denom_pylon.png create mode 100644 evently/assets/images/denom_usd.png create mode 100644 evently/assets/images/text_field_button.png create mode 100644 evently/lib/evently_provider.dart create mode 100644 evently/lib/models/denom.dart create mode 100644 evently/lib/utils/amount_formatter.dart create mode 100644 evently/lib/widgets/evently_price_input_field.dart rename evently/lib/widgets/{easel_text_field.dart => evently_text_field.dart} (100%) diff --git a/evently/assets/images/denom_pylon.png b/evently/assets/images/denom_pylon.png new file mode 100644 index 0000000000000000000000000000000000000000..b4e43bc030e44103893f304c429fc9c0f293c2c5 GIT binary patch literal 804 zcmV+<1Ka$GP)GhHiikuh>|G|IGAhe-Hb3COvV)zJnj$;{1jl|2C#31ZD$fSG4+U~29vNRZM@P9k4OqHsW5lJQYmDLlzTO@#a{+(p#t4Md)R#W6zhfC*jjswiU>?v#bSzuB1^SPYp968 ziLPGNC`-$XT)r1*9v)L|vtdMx_k{%NBQUTa)W#Q6n(#jBsIV_&fg(8E(p!SwgOnq< irN>dC_zWqw^o{}S80M}ArXj`v0000_sXggY7^}pWx?nOe2!IY{6A4Qx$m=V1Iy6Tq2Yvyj5Hx3bNDY;t zDTB%DlW^Tv?23f#)r>(7Ob0kyVOzK$nSZflV)TgJH)#`D6qO)|%w&()KTo@uQR>2~ z5M`K8iLWJ}nL#l`t{5{8V}_z(T?zjI9eBaz!UujTkIs++rC^br?t|j8ibyMl42aH- z1yjvZ(;;(#8*-L!fem<3*%COm(157o0fX}r-Gz|NnLETq>+JXIQS4c^;nUn;o!9GIJ)tM zOds+U60jm;jkurdm=CIA7tiutyU=g4MYiq!-2oOzBSBt}q@}kJ`UZPpmOUMuvlk`Q z(Y<>~E;@BSH22htG#~>d#voXrq4OO)Mqjz*zaS!uOw|@=s*JQnuytIe(42IG35$VntkKikg4JmXDm^gfh*i^D?GHh3k#V+5_Yiym8tOJP(+e3Ni=yza>A)nC((mlz<5EI76$nk`gT1^QC zIO7z_u>)Z$q&`@2#?RwIoC^}*=Nv!d?BSGsuo}yC{G`XlCq1?ucM7iPPQe+i4o0^# jD1z6AG_^XFX;SeQf-|ptuI;pw00000NkvXXu0mjf5mFd) literal 0 HcmV?d00001 diff --git a/evently/assets/images/text_field_button.png b/evently/assets/images/text_field_button.png new file mode 100644 index 0000000000000000000000000000000000000000..3554ba3ac5eb8dbf6ed46362557124334fea8f6d GIT binary patch literal 370 zcmeAS@N?(olHy`uVBq!ia0vp^JwU9@!3HE(-Au>;Qk(@Ik;M!Q+`=Ht$S`Y;1W=H% zILO_JVcj{Imp~3nx}&cn1H;CC?mvmFKsk0#7srqa#<$n@`Z60z98ZjQ@$7oz)S;wh z*65ocVwS+8BITCAqVg&sX&?Wgr~fkFS6ZDe`+hmQ{CoNNtp_|dGcg_%5abc0fLMGr zNS^huhVC@qyK}hP_Sz*!t`}G1Ib3(_(lvM1f5ERWFRM9zX@@?((WGhSrd*xVSN~Y;RGP8UN&zHMlAv=|J9Vn7q~4mnH-SOK;OXk;vd$@? F2>{y$f`R}5 literal 0 HcmV?d00001 diff --git a/evently/i18n/de.json b/evently/i18n/de.json index e52f2127d1..dfa99e77e0 100644 --- a/evently/i18n/de.json +++ b/evently/i18n/de.json @@ -33,5 +33,10 @@ "claim_free_drink": "Claim your free drink at the bar during the event!", "character_limit": "256 character limit", "there_no_perks_created": "There are no perks created.", - "free_shirt": "1 free t-shirt" + "free_shirt": "1 free t-shirt", + "is_free_drop": "Is this a free drop?", + "yes": "Yes", + "no" : "No", + "number_tickets": "Number of Tickets", + "network_fee_listed_price_occur_on_chain": "A network fee of 10% the listed price is required for all transactions that occur on-chain" } \ No newline at end of file diff --git a/evently/i18n/en-US.json b/evently/i18n/en-US.json index e52f2127d1..dfa99e77e0 100644 --- a/evently/i18n/en-US.json +++ b/evently/i18n/en-US.json @@ -33,5 +33,10 @@ "claim_free_drink": "Claim your free drink at the bar during the event!", "character_limit": "256 character limit", "there_no_perks_created": "There are no perks created.", - "free_shirt": "1 free t-shirt" + "free_shirt": "1 free t-shirt", + "is_free_drop": "Is this a free drop?", + "yes": "Yes", + "no" : "No", + "number_tickets": "Number of Tickets", + "network_fee_listed_price_occur_on_chain": "A network fee of 10% the listed price is required for all transactions that occur on-chain" } \ No newline at end of file diff --git a/evently/i18n/es.json b/evently/i18n/es.json index e52f2127d1..dfa99e77e0 100644 --- a/evently/i18n/es.json +++ b/evently/i18n/es.json @@ -33,5 +33,10 @@ "claim_free_drink": "Claim your free drink at the bar during the event!", "character_limit": "256 character limit", "there_no_perks_created": "There are no perks created.", - "free_shirt": "1 free t-shirt" + "free_shirt": "1 free t-shirt", + "is_free_drop": "Is this a free drop?", + "yes": "Yes", + "no" : "No", + "number_tickets": "Number of Tickets", + "network_fee_listed_price_occur_on_chain": "A network fee of 10% the listed price is required for all transactions that occur on-chain" } \ No newline at end of file diff --git a/evently/i18n/ru-RU.json b/evently/i18n/ru-RU.json index e52f2127d1..dfa99e77e0 100644 --- a/evently/i18n/ru-RU.json +++ b/evently/i18n/ru-RU.json @@ -33,5 +33,10 @@ "claim_free_drink": "Claim your free drink at the bar during the event!", "character_limit": "256 character limit", "there_no_perks_created": "There are no perks created.", - "free_shirt": "1 free t-shirt" + "free_shirt": "1 free t-shirt", + "is_free_drop": "Is this a free drop?", + "yes": "Yes", + "no" : "No", + "number_tickets": "Number of Tickets", + "network_fee_listed_price_occur_on_chain": "A network fee of 10% the listed price is required for all transactions that occur on-chain" } \ No newline at end of file diff --git a/evently/lib/evently_provider.dart b/evently/lib/evently_provider.dart new file mode 100644 index 0000000000..d742f7c69c --- /dev/null +++ b/evently/lib/evently_provider.dart @@ -0,0 +1,26 @@ + + + +import 'package:evently/models/denom.dart'; +import 'package:flutter/cupertino.dart'; + +enum FreeDrop { yes, no, unselected } + +class EventlyProvider extends ChangeNotifier { + + Denom _selectedDenom = Denom.availableDenoms.first; + + Denom get selectedDenom => _selectedDenom; + + List supportedDenomList = []; + + TextEditingController priceController = TextEditingController(); + + FreeDrop isFreeDrop = FreeDrop.unselected; + + void setSelectedDenom(Denom value) { + _selectedDenom = value; + notifyListeners(); + } + +} \ No newline at end of file diff --git a/evently/lib/generated/locale_keys.g.dart b/evently/lib/generated/locale_keys.g.dart index a1e7e06fb8..47bf5b4a74 100644 --- a/evently/lib/generated/locale_keys.g.dart +++ b/evently/lib/generated/locale_keys.g.dart @@ -36,5 +36,10 @@ abstract class LocaleKeys { static const character_limit = 'character_limit'; static const there_no_perks_created = 'there_no_perks_created'; static const free_shirt = 'free_shirt'; + static const is_free_drop = 'is_free_drop'; + static const yes = 'yes'; + static const no = 'no'; + static const number_tickets = 'number_tickets'; + static const network_fee_listed_price_occur_on_chain = 'network_fee_listed_price_occur_on_chain'; } diff --git a/evently/lib/models/denom.dart b/evently/lib/models/denom.dart new file mode 100644 index 0000000000..1c94ab5551 --- /dev/null +++ b/evently/lib/models/denom.dart @@ -0,0 +1,84 @@ +import 'package:evently/utils/amount_formatter.dart'; +import 'package:evently/utils/constants.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; + +import '../main.dart'; + +class Denom { + final String name; + final String symbol; + final String icon; + + Denom({required this.name, required this.symbol, required this.icon}); + + factory Denom.initial() { + return Denom(icon: '', name: '', symbol: ''); + } + + static List get availableDenoms => [ + Denom(name: kUSDText, symbol: kUsdSymbol, icon: PngUtils.kIconDenomUsd), + Denom(name: kPylonText, symbol: kPylonSymbol, icon: PngUtils.kIconDenomPylon), + ]; + + TextInputFormatter getFormatter() { + if (symbol == kPylonSymbol) { + return AmountFormatter(maxDigits: kMaxPriceLength); + } + return AmountFormatter(maxDigits: kMaxPriceLength, isDecimal: true); + } + + @override + String toString() { + return 'Denom{name: $name, symbol: $symbol, icon: $icon}'; + } + + Widget getIconWidget() { + switch (symbol) { + case kUsdSymbol: + case kPylonSymbol: + case kAtomSymbol: + case kEuroSymbol: + case kJunoSymbol: + return Image.asset( + icon, + height: 20.h, + fit: BoxFit.contain, + width: 20.w, + ); + case kEthereumSymbol: + return Container( + padding: EdgeInsets.symmetric(vertical: isTablet ? 5.h : 10.h), + child: Image.asset( + icon, + height: 20.h, + )); + case kAgoricSymbol: + return Image.asset( + icon, + height: 15.h, + width: 15.w, + fit: BoxFit.contain, + ); + default: + return Image.asset(icon); + } + } + + String formatAmount({required String price}) { + switch (symbol) { + case kUsdSymbol: + case kPylonSymbol: + case kAtomSymbol: + case kEuroSymbol: + case kAgoricSymbol: + case kJunoSymbol: + return (double.parse(price.replaceAll(",", "").trim()) * kBigIntBase).toStringAsFixed(0); + case kEthereumSymbol: + return (double.parse(price.replaceAll(",", "").trim()) * kEthIntBase).toStringAsFixed(0); + default: + return (double.parse(price.replaceAll(",", "").trim()) * kBigIntBase).toStringAsFixed(0); + } + } +} diff --git a/evently/lib/screens/detail_screen.dart b/evently/lib/screens/detail_screen.dart index 3e47e8cd04..65884fcc66 100644 --- a/evently/lib/screens/detail_screen.dart +++ b/evently/lib/screens/detail_screen.dart @@ -6,7 +6,7 @@ import 'package:evently/utils/evently_app_theme.dart'; import 'package:evently/utils/space_utils.dart'; import 'package:evently/viewmodels/create_event_viewmodel.dart'; import 'package:evently/widgets/clipped_button.dart'; -import 'package:evently/widgets/easel_text_field.dart'; +import 'package:evently/widgets/evently_text_field.dart'; import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:provider/provider.dart'; diff --git a/evently/lib/screens/overview_screen.dart b/evently/lib/screens/overview_screen.dart index 2cddf9f312..8917dc63ec 100644 --- a/evently/lib/screens/overview_screen.dart +++ b/evently/lib/screens/overview_screen.dart @@ -8,7 +8,7 @@ import 'package:evently/utils/evently_app_theme.dart'; import 'package:evently/utils/space_utils.dart'; import 'package:evently/viewmodels/create_event_viewmodel.dart'; import 'package:evently/widgets/clipped_button.dart'; -import 'package:evently/widgets/easel_text_field.dart'; +import 'package:evently/widgets/evently_text_field.dart'; import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:flutter_svg/flutter_svg.dart'; diff --git a/evently/lib/screens/perks_screen.dart b/evently/lib/screens/perks_screen.dart index 66da0da1c4..6da878b98a 100644 --- a/evently/lib/screens/perks_screen.dart +++ b/evently/lib/screens/perks_screen.dart @@ -8,7 +8,7 @@ import 'package:evently/utils/screen_responsive.dart'; import 'package:evently/utils/space_utils.dart'; import 'package:evently/viewmodels/create_event_viewmodel.dart'; import 'package:evently/widgets/clipped_button.dart'; -import 'package:evently/widgets/easel_text_field.dart'; +import 'package:evently/widgets/evently_text_field.dart'; import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:flutter_svg/flutter_svg.dart'; diff --git a/evently/lib/screens/price_screen.dart b/evently/lib/screens/price_screen.dart index 5bdbc6c110..61360c9ac6 100644 --- a/evently/lib/screens/price_screen.dart +++ b/evently/lib/screens/price_screen.dart @@ -1,15 +1,260 @@ + +import 'package:easy_localization/easy_localization.dart'; +import 'package:evently/evently_provider.dart'; +import 'package:evently/screens/custom_widgets/step_labels.dart'; +import 'package:evently/screens/custom_widgets/steps_indicator.dart'; +import 'package:evently/utils/amount_formatter.dart'; +import 'package:evently/utils/constants.dart'; +import 'package:evently/utils/evently_app_theme.dart'; +import 'package:evently/utils/screen_responsive.dart'; +import 'package:evently/utils/space_utils.dart'; +import 'package:evently/viewmodels/create_event_viewmodel.dart'; +import 'package:evently/widgets/clipped_button.dart'; +import 'package:evently/widgets/evently_price_input_field.dart'; +import 'package:evently/widgets/evently_text_field.dart'; import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; +import 'package:get_it/get_it.dart'; +import 'package:provider/provider.dart'; + +import '../generated/locale_keys.g.dart'; class PriceScreen extends StatefulWidget { - const PriceScreen({super.key}); + const PriceScreen({Key? key}) : super(key: key); @override State createState() => _PriceScreenState(); } class _PriceScreenState extends State { + final _formKey = GlobalKey(); + final ValueNotifier _priceFieldError = ValueNotifier(""); + + @override + void dispose() { + _formKey.currentState?.dispose(); + super.dispose(); + } + + @override + void initState() { + super.initState(); + } + @override Widget build(BuildContext context) { - return const Placeholder(); + final homeViewModel = context.watch(); + + return Scaffold( + body: SingleChildScrollView( + child: Consumer(builder: (_, provider, __) { + return Form( + key: _formKey, + child: Column( + children: [ + const VerticalSpace(20), + MyStepsIndicator(currentStep: homeViewModel.currentStep), + const VerticalSpace(5), + StepLabels(currentPage: homeViewModel.currentPage, currentStep: homeViewModel.currentStep), + const VerticalSpace(10), + const VerticalSpace(20), + Stack( + alignment: Alignment.center, + children: [ + Align( + alignment: Alignment.centerLeft, + child: ValueListenableBuilder( + valueListenable: homeViewModel.currentPage, + builder: (_, int currentPage, __) => Padding( + padding: EdgeInsets.only(left: 10.sp), + child: IconButton( + onPressed: () { + ScaffoldMessenger.of(context).hideCurrentSnackBar(); + homeViewModel.previousPage(); + }, + icon: const Icon( + Icons.arrow_back_ios, + color: EventlyAppTheme.kGrey, + ), + )), + )), + ValueListenableBuilder( + valueListenable: homeViewModel.currentPage, + builder: (_, int currentPage, __) { + return Text( + homeViewModel.pageTitles[homeViewModel.currentPage.value], + style: Theme.of(context).textTheme.bodyLarge!.copyWith(fontSize: 18.sp, fontWeight: FontWeight.w700, color: EventlyAppTheme.kDarkText), + ); + }, + ), + ], + ), + ScreenResponsive( + mobileScreen: (context) => const VerticalSpace(6), + tabletScreen: (context) => const VerticalSpace(30), + ), + VerticalSpace(10.h), + Padding( + padding: EdgeInsets.symmetric(horizontal: 20.w, vertical: 15.h), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + LocaleKeys.is_free_drop.tr(), + style: TextStyle(fontSize: 18.sp, fontWeight: FontWeight.w700), + ), + SizedBox( + height: 10.h, + ), + Row(children: [ + InkWell( + onTap: () { + // provider.updateIsFreeDropStatus(FreeDrop.yes); + }, + child: Container( + width: 140.w, + height: 30.h, + decoration: BoxDecoration( + color: provider.isFreeDrop == FreeDrop.yes ? EventlyAppTheme.kBlue : EventlyAppTheme.kTransparent, + border: Border.all(color: provider.isFreeDrop == FreeDrop.yes ? EventlyAppTheme.kBlue : EventlyAppTheme.kBlack, width: 2.w), + ), + child: Center( + child: Text( + LocaleKeys.yes.tr(), + style: TextStyle( + color: provider.isFreeDrop == FreeDrop.yes ? EventlyAppTheme.kWhite : EventlyAppTheme.kBlack, + ), + ), + ), + ), + ), + SizedBox( + width: 30.w, + ), + InkWell( + onTap: () { + + }, + child: Container( + width: 140.w, + height: 30.h, + decoration: BoxDecoration( + color: provider.isFreeDrop == FreeDrop.no ? EventlyAppTheme.kBlue : EventlyAppTheme.kTransparent, + border: Border.all(color: provider.isFreeDrop == FreeDrop.no ? EventlyAppTheme.kBlue : EventlyAppTheme.kBlack, width: 2.w), + ), + child: Center( + child: Text( + LocaleKeys.no.tr(), + style: TextStyle( + color: provider.isFreeDrop == FreeDrop.no ? EventlyAppTheme.kWhite : EventlyAppTheme.kBlack, + ), + ), + ), + ), + ), + ]), + if (provider.isFreeDrop != FreeDrop.unselected) + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + if (provider.isFreeDrop == FreeDrop.no) + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + VerticalSpace(20.h), + EventlyPriceInputField( + key: ValueKey("${provider.selectedDenom.name}-amount"), + inputFormatters: [FilteringTextInputFormatter.digitsOnly, LengthLimitingTextInputFormatter(kMaxPriceLength), provider.selectedDenom.getFormatter()], + controller: provider.priceController, + validator: (value) { + + }, + ), + + Text( + LocaleKeys.network_fee_listed_price_occur_on_chain.tr(), + style: TextStyle(color: EventlyAppTheme.kLightPurple, fontSize: 14.sp, fontWeight: FontWeight.w800), + ), + ], + ), + + ], + ), + if (provider.isFreeDrop == FreeDrop.unselected) + ScreenResponsive( + mobileScreen: (_) => VerticalSpace(0.38.sh), + tabletScreen: (_) => VerticalSpace(0.2.sh), + ), + if (provider.isFreeDrop == FreeDrop.yes) + ScreenResponsive( + mobileScreen: (_) => VerticalSpace(0.1.sh), + tabletScreen: (_) => VerticalSpace(0.05.sh), + ), + VerticalSpace(20.h), + ClippedButton( + title: LocaleKeys.continue_key.tr(), + bgColor: provider.isFreeDrop != FreeDrop.unselected ? EventlyAppTheme.kBlue : EventlyAppTheme.kPurple03, + textColor: EventlyAppTheme.kWhite, + onPressed: () async { + if (provider.isFreeDrop != FreeDrop.unselected) { + FocusScope.of(context).unfocus(); + validateAndUpdatePrice(moveNextPage: true); + } + }, + cuttingHeight: 15.h, + clipperType: ClipperType.bottomLeftTopRight, + isShadow: false, + fontWeight: FontWeight.w700, + ), + VerticalSpace(10.h), + Center( + child: InkWell( + + onTap: () { + if (provider.isFreeDrop == FreeDrop.unselected) { + Navigator.pop(context); + return; + } + FocusScope.of(context).unfocus(); + validateAndUpdatePrice(moveNextPage: false); + }, + child: Text( + LocaleKeys.save_as_draft.tr(), + style: TextStyle(color: EaselAppTheme.kLightGreyText, fontSize: 14.sp, fontWeight: FontWeight.w700), + ), + ), + ), + VerticalSpace(5.h), + ], + ), + ), + ], + ), + ); + }), + ), + ); + } + + Future validateAndUpdatePrice({required bool moveNextPage}) async { + final navigator = Navigator.of(context); + final HomeViewModel homeViewModel = context.read(); + + if (!_formKey.currentState!.validate()) { + return; + } + GetIt.I.get().changeSelectedCollection(CollectionType.draft); + + if (context.read().isFreeDrop == FreeDrop.yes) { + if (_royaltiesFieldError.value.isNotEmpty || _noOfEditionsFieldError.value.isNotEmpty) return; + await context.read().updateNftFromPrice(nft!.id!); + moveNextPage ? homeViewModel.nextPage() : navigator.pop(); + + return; + } + if (_royaltiesFieldError.value.isNotEmpty || _noOfEditionsFieldError.value.isNotEmpty || _priceFieldError.value.isNotEmpty) return; + await context.read().updateNftFromPrice(nft!.id!); + moveNextPage ? homeViewModel.nextPage() : navigator.pop(); } } diff --git a/evently/lib/utils/amount_formatter.dart b/evently/lib/utils/amount_formatter.dart new file mode 100644 index 0000000000..246092db6d --- /dev/null +++ b/evently/lib/utils/amount_formatter.dart @@ -0,0 +1,28 @@ +import 'package:flutter/services.dart'; +import 'package:intl/intl.dart'; + +class AmountFormatter extends TextInputFormatter { + AmountFormatter({required this.maxDigits, this.isDecimal = false}); + + int maxDigits; + bool isDecimal; + + @override + TextEditingValue formatEditUpdate( + TextEditingValue oldValue, TextEditingValue newValue) { + maxDigits = 20; + if (newValue.selection.baseOffset == 0) { + return newValue; + } + if (newValue.selection.baseOffset > maxDigits) { + return oldValue; + } + final double value = double.parse(newValue.text); + final formatter = NumberFormat(isDecimal ? "#,##0.00" : "#,###", "en_US"); + final String newText = formatter.format(isDecimal ? value / 100 : value); + + return newValue.copyWith( + text: newText, + selection: TextSelection.collapsed(offset: newText.length)); + } +} diff --git a/evently/lib/utils/constants.dart b/evently/lib/utils/constants.dart index 6dc9923896..ee5435b429 100644 --- a/evently/lib/utils/constants.dart +++ b/evently/lib/utils/constants.dart @@ -6,6 +6,27 @@ const kDraft = "Draft"; final List stepLabels = ["overview", "detail", "perks", "price"]; +const kPylonSymbol = 'upylon'; +const kUsdSymbol = 'ustripeusd'; +const kAtomSymbol = 'uatom'; +const kEuroSymbol = 'eeur'; +const kAgoricSymbol = 'urun'; +const kJunoSymbol = 'ujunox'; +const String kEthereumSymbol = "weth-wei"; + +const kPylonText = 'Pylon'; +const kUSDText = 'USD'; +const kAtomText = 'Atom'; +const kEurText = 'EEur'; +const kAgoricText = 'Agoric'; +const kJunoText = 'Juno'; +const kEthereum = "Ethereum"; + +const kMaxPriceLength = 14; +const int kBigIntBase = 1000000; +const int kEthIntBase = 1000000000000000000; + + /// ```SVG assets class SVGUtils { static const kSvgSplash = 'assets/images/svg/splash.svg'; @@ -22,4 +43,7 @@ class PngUtils { static const kTextFieldMultiLine = 'assets/images/text_field_multi_line.png'; static const kDarkPurpleSingleLine = 'assets/images/svg/dark_purple_single_line.png'; static const kLightPurpleSingleLine = 'assets/images/svg/light_purple_single_line.png'; + static const kTextFieldButton = 'assets/images/text_field_button.png'; + static const kIconDenomUsd = 'assets/images/denom_usd.png'; + static const kIconDenomPylon = 'assets/images/denom_pylon.png'; } diff --git a/evently/lib/widgets/evently_price_input_field.dart b/evently/lib/widgets/evently_price_input_field.dart new file mode 100644 index 0000000000..6ecacec8dc --- /dev/null +++ b/evently/lib/widgets/evently_price_input_field.dart @@ -0,0 +1,113 @@ +import 'package:easy_localization/easy_localization.dart'; +import 'package:evently/evently_provider.dart'; +import 'package:evently/utils/constants.dart'; +import 'package:evently/utils/evently_app_theme.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; +import 'package:provider/provider.dart'; +import '../generated/locale_keys.g.dart'; +import '../main.dart'; +import '../models/denom.dart'; + +class EventlyPriceInputField extends StatelessWidget { + const EventlyPriceInputField({super.key, this.controller, this.validator, this.inputFormatters = const []}); + + final TextEditingController? controller; + final String? Function(String?)? validator; + final List inputFormatters; + + @override + Widget build(BuildContext context) { + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + LocaleKeys.price.tr(), + textAlign: TextAlign.start, + style: TextStyle(fontSize: 18.sp, fontWeight: FontWeight.w700), + ), + SizedBox(height: 4.h), + Stack( + children: [ + Positioned( + child: Image.asset(PngUtils.kTextFieldSingleLine, width: 1.sw, height: isTablet ? 32.h : 40.h, fit: BoxFit.fill), + ), + Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Expanded( + child: TextFormField( + style: TextStyle(fontSize: 18.sp, fontWeight: FontWeight.w400, color: EventlyAppTheme.kDarkText), + controller: controller, + validator: validator, + minLines: 1, + keyboardType: TextInputType.number, + inputFormatters: inputFormatters, + decoration: InputDecoration( + hintText: LocaleKeys.network_fee_listed_price_occur_on_chain.tr(), + hintStyle: TextStyle(fontSize: 15.sp, fontWeight: FontWeight.w400, color: EventlyAppTheme.kGrey), + border: const OutlineInputBorder(borderSide: BorderSide.none), + floatingLabelBehavior: FloatingLabelBehavior.always, + contentPadding: EdgeInsets.fromLTRB(10.w, 0.h, 10.w, 0.h)))), + const _CurrencyDropDown() + ], + ), + ], + ), + ], + ); + } +} + +class _CurrencyDropDown extends StatelessWidget { + const _CurrencyDropDown({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return Consumer( + builder: (_, provider, __) => Stack( + alignment: Alignment.center, + children: [ + Positioned(left: 0, top: 0, bottom: 0, right: 0, child: Image.asset(PngUtils.kTextFieldButton, height: isTablet ? 32.h : 40.h, fit: BoxFit.fill)), + Container( + padding: EdgeInsets.only(left: 5.w), + height: isTablet ? 32.h : 40.h, + child: Align( + child: DropdownButton( + onTap: () { + FocusManager.instance.primaryFocus?.unfocus(); + }, + value: provider.selectedDenom.symbol, + iconSize: 0, + elevation: 0, + underline: const SizedBox(), + dropdownColor: EventlyAppTheme.kPurple03, + style: TextStyle(color: EventlyAppTheme.kWhite, fontSize: 18.sp, fontWeight: FontWeight.w400), + onChanged: (String? data) { + if (data != null) { + final value = provider.supportedDenomList.firstWhere((denom) => denom.symbol == data); + provider.priceController.clear(); + provider.setSelectedDenom(value); + } + }, + items: provider.supportedDenomList.map((Denom value) { + return DropdownMenuItem( + value: value.symbol, + child: Row(children: [ + value.getIconWidget(), + SizedBox(width: isTablet ? 10.w : 10.w), + Text( + value.name, + style: TextStyle(fontSize: isTablet ? 16.sp : 18.sp), + ), + SizedBox(width: isTablet ? 0.w : 5.w), + ]), + ); + }).toList(), + ), + )), + ], + )); + } +} diff --git a/evently/lib/widgets/easel_text_field.dart b/evently/lib/widgets/evently_text_field.dart similarity index 100% rename from evently/lib/widgets/easel_text_field.dart rename to evently/lib/widgets/evently_text_field.dart