diff --git a/lib/application/airdrop/airdrop.dart b/lib/application/airdrop/airdrop.dart index a9eca60b3..247ebe796 100644 --- a/lib/application/airdrop/airdrop.dart +++ b/lib/application/airdrop/airdrop.dart @@ -1,5 +1,10 @@ import 'dart:convert'; +import 'package:aewallet/application/api_service.dart'; +import 'package:aewallet/application/session/session.dart'; +import 'package:aewallet/modules/aeswap/application/farm/farm_lock_factory.dart'; +import 'package:aewallet/modules/aeswap/domain/models/util/get_farm_lock_user_infos_response.dart'; +import 'package:aewallet/ui/views/aeswap_earn/bloc/provider.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:http/http.dart' as http; import 'package:logging/logging.dart'; @@ -29,3 +34,82 @@ Future airdropCount( } return null; } + +@riverpod +Future airdropPersonalRewards( + Ref ref, +) async { + final keychain = ref.watch( + sessionNotifierProvider.select( + (value) => value.loggedIn?.wallet.appKeychain, + ), + ); + + if (keychain == null) return 0.0; + + final apiService = ref.watch(apiServiceProvider); + final farmLock = ref.watch(farmLockFormFarmLockProvider).valueOrNull; + + if (farmLock == null) return 0.0; + + final farmFactory = FarmLockFactory(farmLock.farmAddress, apiService); + + var personalLP = 0.0; + final userGenesisAddresses = + keychain.accounts.map((account) => account.genesisAddress).toList(); + + const batchSize = 20; + + for (var i = 0; i < userGenesisAddresses.length; i += batchSize) { + final batch = userGenesisAddresses.sublist( + i, + (i + batchSize > userGenesisAddresses.length) + ? userGenesisAddresses.length + : i + batchSize, + ); + + final results = await farmFactory.getUserInfosFromMultipleAddresses(batch); + + for (final result in results) { + for (final userInfos in result) { + final userInfosResponse = UserInfos.fromJson(userInfos!); + personalLP += userInfosResponse.amount; + } + } + } + return personalLP; +} + +@riverpod +Future airdropPersonalMultiplier( + Ref ref, +) async { + final airdropPersonalRewards = + await ref.watch(airdropPersonalRewardsProvider.future); + + return _getMultiplier(airdropPersonalRewards); +} + +int? _getMultiplier(double x) { + if (1 <= x && x < 5) { + return 1; + } else if (5 <= x && x < 20) { + return 2; + } else if (20 <= x && x < 60) { + return 3; + } else if (60 <= x && x < 150) { + return 5; + } else if (150 <= x && x < 300) { + return 8; + } else if (300 <= x && x < 500) { + return 13; + } else if (500 <= x && x < 750) { + return 21; + } else if (750 <= x && x < 1000) { + return 34; + } else if (x >= 1000) { + return 55; + } else { + return null; + } +} diff --git a/lib/application/airdrop/airdrop.g.dart b/lib/application/airdrop/airdrop.g.dart index b936b2312..5250a930b 100644 --- a/lib/application/airdrop/airdrop.g.dart +++ b/lib/application/airdrop/airdrop.g.dart @@ -22,5 +22,43 @@ final airdropCountProvider = AutoDisposeFutureProvider.internal( @Deprecated('Will be removed in 3.0. Use Ref instead') // ignore: unused_element typedef AirdropCountRef = AutoDisposeFutureProviderRef; +String _$airdropPersonalRewardsHash() => + r'ac78a325d8787fab435946970bc369d3a3cd297b'; + +/// See also [airdropPersonalRewards]. +@ProviderFor(airdropPersonalRewards) +final airdropPersonalRewardsProvider = + AutoDisposeFutureProvider.internal( + airdropPersonalRewards, + name: r'airdropPersonalRewardsProvider', + debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product') + ? null + : _$airdropPersonalRewardsHash, + dependencies: null, + allTransitiveDependencies: null, +); + +@Deprecated('Will be removed in 3.0. Use Ref instead') +// ignore: unused_element +typedef AirdropPersonalRewardsRef = AutoDisposeFutureProviderRef; +String _$airdropPersonalMultiplierHash() => + r'15549af92c8eb0e4820ffca218cd29c8f47bb899'; + +/// See also [airdropPersonalMultiplier]. +@ProviderFor(airdropPersonalMultiplier) +final airdropPersonalMultiplierProvider = + AutoDisposeFutureProvider.internal( + airdropPersonalMultiplier, + name: r'airdropPersonalMultiplierProvider', + debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product') + ? null + : _$airdropPersonalMultiplierHash, + dependencies: null, + allTransitiveDependencies: null, +); + +@Deprecated('Will be removed in 3.0. Use Ref instead') +// ignore: unused_element +typedef AirdropPersonalMultiplierRef = AutoDisposeFutureProviderRef; // ignore_for_file: type=lint // ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member, deprecated_member_use_from_same_package diff --git a/lib/l10n/intl_en.arb b/lib/l10n/intl_en.arb index f8298a8c2..28d44fef4 100644 --- a/lib/l10n/intl_en.arb +++ b/lib/l10n/intl_en.arb @@ -702,6 +702,13 @@ "airdropParticipateStepWaitlistDesc2": "Only one airdrop registration is allowed per person. If multiple registrations are detected, all associated airdrops will be canceled.", "airdropParticipateStepWaitlistInputField": "Email Address", "airdropParticipateStepWaitlistBtn": "Join the waitlist", + "airdropParticipateStepConfirmEmailTitle": "Your registration is almost complete!", + "airdropParticipateStepConfirmEmailDesc1": "To finalize your participation, please check your inbox and click the confirmation link we just sent at:", + "airdropParticipateStepConfirmEmailDesc2": "Didn’t receive the email? Check your spam folder or ", + "airdropParticipateStepConfirmEmailDesc3": "click here to resend the confirmation email.", + "airdropParticipateStepConfirmEmailDesc4": "Wrong email?", + "airdropParticipateStepConfirmEmailDesc5": "Edit it here.", + "airdropParticipateStepConfirmEmailDesc6": "Your participation will only be validated once your email is confirmed.", "airdropParticipateStepSupportEcosystemTitle": "The last step to participate in the airdrop is to support our ecosystem and earn rewards.", "airdropParticipateStepSupportEcosystemDesc1": "Participate in our passive income program, currently offering an impressive ", "airdropParticipateStepSupportEcosystemDesc2": "! Simply add liquidity to the aeETH/UCO pool, then farm your LP (Liquidity Provider) tokens in our passive income program.\nThe more liquidity you provide, the greater your multiplier in the airdrop.", diff --git a/lib/modules/aeswap/application/farm/farm_lock_factory.dart b/lib/modules/aeswap/application/farm/farm_lock_factory.dart index 6e6a1378c..d8c7964ad 100644 --- a/lib/modules/aeswap/application/farm/farm_lock_factory.dart +++ b/lib/modules/aeswap/application/farm/farm_lock_factory.dart @@ -76,4 +76,40 @@ class FarmLockFactory with ModelParser { return results; } + + /// Returns the informations of multiple addresses who has deposited and locked lp token in the farm + Future> getUserInfosFromMultipleAddresses( + List userGenesisAddresses, + ) async { + if (userGenesisAddresses.isEmpty) { + return []; + } + + final scCallFunctionRequestList = []; + for (final userGenesisAddress in userGenesisAddresses) { + scCallFunctionRequestList.add( + SCCallFunctionRequest( + method: 'contract_fun', + params: SCCallFunctionParams( + contract: factoryAddress.toUpperCase(), + function: 'get_user_infos', + args: [userGenesisAddress], + ), + ), + ); + } + + final results = await apiService.callSCFunctionMulti( + jsonRPCRequests: scCallFunctionRequestList, + ); + + final userinfos = []; + for (final result in results) { + if (result['result'] != null && (result['result'] as List).isNotEmpty) { + userinfos.add(result['result']); + } + } + + return userinfos; + } } diff --git a/lib/ui/views/airdrop/bloc/provider.dart b/lib/ui/views/airdrop/bloc/provider.dart index 9deb68fb4..24ae6b575 100644 --- a/lib/ui/views/airdrop/bloc/provider.dart +++ b/lib/ui/views/airdrop/bloc/provider.dart @@ -18,7 +18,9 @@ class AirdropFormNotifier extends _$AirdropFormNotifier { AirdropFormNotifier(); @override - AirdropFormState build() => const AirdropFormState(); + AirdropFormState build() { + return const AirdropFormState(); + } void setConfirmOnlyOneAirdrop(bool confirmOnlyOneAirdrop) { state = state.copyWith( @@ -63,7 +65,7 @@ class AirdropFormNotifier extends _$AirdropFormNotifier { if (!state.isItemsConfirmed) { state = state.copyWith( failure: const Failure.other( - message: 'Formulaire invalide', + message: 'Invalid Forms', ), joinWaitlistInProgress: false, ); diff --git a/lib/ui/views/airdrop/bloc/provider.g.dart b/lib/ui/views/airdrop/bloc/provider.g.dart index 4e904198e..cb237586b 100644 --- a/lib/ui/views/airdrop/bloc/provider.g.dart +++ b/lib/ui/views/airdrop/bloc/provider.g.dart @@ -7,7 +7,7 @@ part of 'provider.dart'; // ************************************************************************** String _$airdropFormNotifierHash() => - r'b714930be4c05fcb777af209cfa33b9c6d550579'; + r'844f885315bd017dfe02d72f3b196a5ec505b82b'; /// See also [AirdropFormNotifier]. @ProviderFor(AirdropFormNotifier) diff --git a/lib/ui/views/airdrop/bloc/state.dart b/lib/ui/views/airdrop/bloc/state.dart index 4972e2068..3a4bd58b9 100644 --- a/lib/ui/views/airdrop/bloc/state.dart +++ b/lib/ui/views/airdrop/bloc/state.dart @@ -7,6 +7,7 @@ part 'state.freezed.dart'; enum AirdropProcessStep { welcome, joinWaitlist, + confirmEmail, supportEcosystem, sign, congrats @@ -21,6 +22,7 @@ class AirdropFormState with _$AirdropFormState { @Default(false) bool confirmNotMultipleRegistrations, @Default(false) bool confirmPrivacyPolicy, @Default(false) bool joinWaitlistInProgress, + @Default(0.0) double personalLP, Failure? failure, }) = _AirdropFormState; const AirdropFormState._(); diff --git a/lib/ui/views/airdrop/bloc/state.freezed.dart b/lib/ui/views/airdrop/bloc/state.freezed.dart index f7b8d7178..601857003 100644 --- a/lib/ui/views/airdrop/bloc/state.freezed.dart +++ b/lib/ui/views/airdrop/bloc/state.freezed.dart @@ -24,6 +24,7 @@ mixin _$AirdropFormState { throw _privateConstructorUsedError; bool get confirmPrivacyPolicy => throw _privateConstructorUsedError; bool get joinWaitlistInProgress => throw _privateConstructorUsedError; + double get personalLP => throw _privateConstructorUsedError; Failure? get failure => throw _privateConstructorUsedError; /// Create a copy of AirdropFormState @@ -46,6 +47,7 @@ abstract class $AirdropFormStateCopyWith<$Res> { bool confirmNotMultipleRegistrations, bool confirmPrivacyPolicy, bool joinWaitlistInProgress, + double personalLP, Failure? failure}); $FailureCopyWith<$Res>? get failure; @@ -72,6 +74,7 @@ class _$AirdropFormStateCopyWithImpl<$Res, $Val extends AirdropFormState> Object? confirmNotMultipleRegistrations = null, Object? confirmPrivacyPolicy = null, Object? joinWaitlistInProgress = null, + Object? personalLP = null, Object? failure = freezed, }) { return _then(_value.copyWith( @@ -99,6 +102,10 @@ class _$AirdropFormStateCopyWithImpl<$Res, $Val extends AirdropFormState> ? _value.joinWaitlistInProgress : joinWaitlistInProgress // ignore: cast_nullable_to_non_nullable as bool, + personalLP: null == personalLP + ? _value.personalLP + : personalLP // ignore: cast_nullable_to_non_nullable + as double, failure: freezed == failure ? _value.failure : failure // ignore: cast_nullable_to_non_nullable @@ -136,6 +143,7 @@ abstract class _$$AirdropFormStateImplCopyWith<$Res> bool confirmNotMultipleRegistrations, bool confirmPrivacyPolicy, bool joinWaitlistInProgress, + double personalLP, Failure? failure}); @override @@ -161,6 +169,7 @@ class __$$AirdropFormStateImplCopyWithImpl<$Res> Object? confirmNotMultipleRegistrations = null, Object? confirmPrivacyPolicy = null, Object? joinWaitlistInProgress = null, + Object? personalLP = null, Object? failure = freezed, }) { return _then(_$AirdropFormStateImpl( @@ -188,6 +197,10 @@ class __$$AirdropFormStateImplCopyWithImpl<$Res> ? _value.joinWaitlistInProgress : joinWaitlistInProgress // ignore: cast_nullable_to_non_nullable as bool, + personalLP: null == personalLP + ? _value.personalLP + : personalLP // ignore: cast_nullable_to_non_nullable + as double, failure: freezed == failure ? _value.failure : failure // ignore: cast_nullable_to_non_nullable @@ -206,6 +219,7 @@ class _$AirdropFormStateImpl extends _AirdropFormState { this.confirmNotMultipleRegistrations = false, this.confirmPrivacyPolicy = false, this.joinWaitlistInProgress = false, + this.personalLP = 0.0, this.failure}) : super._(); @@ -227,11 +241,14 @@ class _$AirdropFormStateImpl extends _AirdropFormState { @JsonKey() final bool joinWaitlistInProgress; @override + @JsonKey() + final double personalLP; + @override final Failure? failure; @override String toString() { - return 'AirdropFormState(airdropProcessStep: $airdropProcessStep, mailAddress: $mailAddress, confirmOnlyOneAirdrop: $confirmOnlyOneAirdrop, confirmNotMultipleRegistrations: $confirmNotMultipleRegistrations, confirmPrivacyPolicy: $confirmPrivacyPolicy, joinWaitlistInProgress: $joinWaitlistInProgress, failure: $failure)'; + return 'AirdropFormState(airdropProcessStep: $airdropProcessStep, mailAddress: $mailAddress, confirmOnlyOneAirdrop: $confirmOnlyOneAirdrop, confirmNotMultipleRegistrations: $confirmNotMultipleRegistrations, confirmPrivacyPolicy: $confirmPrivacyPolicy, joinWaitlistInProgress: $joinWaitlistInProgress, personalLP: $personalLP, failure: $failure)'; } @override @@ -253,6 +270,8 @@ class _$AirdropFormStateImpl extends _AirdropFormState { other.confirmPrivacyPolicy == confirmPrivacyPolicy) && (identical(other.joinWaitlistInProgress, joinWaitlistInProgress) || other.joinWaitlistInProgress == joinWaitlistInProgress) && + (identical(other.personalLP, personalLP) || + other.personalLP == personalLP) && (identical(other.failure, failure) || other.failure == failure)); } @@ -265,6 +284,7 @@ class _$AirdropFormStateImpl extends _AirdropFormState { confirmNotMultipleRegistrations, confirmPrivacyPolicy, joinWaitlistInProgress, + personalLP, failure); /// Create a copy of AirdropFormState @@ -285,6 +305,7 @@ abstract class _AirdropFormState extends AirdropFormState { final bool confirmNotMultipleRegistrations, final bool confirmPrivacyPolicy, final bool joinWaitlistInProgress, + final double personalLP, final Failure? failure}) = _$AirdropFormStateImpl; const _AirdropFormState._() : super._(); @@ -301,6 +322,8 @@ abstract class _AirdropFormState extends AirdropFormState { @override bool get joinWaitlistInProgress; @override + double get personalLP; + @override Failure? get failure; /// Create a copy of AirdropFormState diff --git a/lib/ui/views/airdrop/layouts/airdrop_dashboard_sheet.dart b/lib/ui/views/airdrop/layouts/airdrop_dashboard_sheet.dart index 5108516a5..32832efe8 100755 --- a/lib/ui/views/airdrop/layouts/airdrop_dashboard_sheet.dart +++ b/lib/ui/views/airdrop/layouts/airdrop_dashboard_sheet.dart @@ -1,9 +1,12 @@ import 'package:aewallet/application/account/accounts_notifier.dart'; +import 'package:aewallet/application/airdrop/airdrop.dart'; import 'package:aewallet/application/settings/settings.dart'; import 'package:aewallet/modules/aeswap/ui/views/util/app_styles.dart'; import 'package:aewallet/ui/themes/archethic_theme.dart'; import 'package:aewallet/ui/util/dimens.dart'; import 'package:aewallet/ui/views/airdrop/layouts/components/airdrop_lp_current_value.dart'; +import 'package:aewallet/ui/views/airdrop/layouts/components/airdrop_personal_multiplier.dart'; +import 'package:aewallet/ui/views/airdrop/layouts/components/airdrop_personal_rewards.dart'; import 'package:aewallet/ui/views/airdrop/layouts/components/airdrop_step_tab.dart'; import 'package:aewallet/ui/views/main/bloc/providers.dart'; import 'package:aewallet/ui/views/main/components/sheet_appbar.dart'; @@ -89,6 +92,17 @@ class _AirdropDashboardSheetState extends ConsumerState @override Widget getSheetContent(BuildContext context, WidgetRef ref) { final localizations = AppLocalizations.of(context)!; + final airdropPersonalMultiplierAsync = + ref.watch(airdropPersonalMultiplierProvider); + int? personalMultiplier; + airdropPersonalMultiplierAsync.when( + data: (data) { + personalMultiplier = data; + }, + error: (_, __) {}, + loading: () {}, + ); + return SingleChildScrollView( child: Column( crossAxisAlignment: CrossAxisAlignment.start, @@ -99,9 +113,19 @@ class _AirdropDashboardSheetState extends ConsumerState .copyWith(fontWeight: FontWeight.bold), ), const SizedBox(height: 20), + Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + AirdropPersonalMultiplier( + personalMultiplier: personalMultiplier, + ), + const AirdropPersonalRewards(), + ], + ), + const SizedBox(height: 20), const AirdropLPCurrentValue(), const SizedBox(height: 10), - const AirdropStepTab(), + AirdropStepTab(personalMultiplier: personalMultiplier), const SizedBox(height: 20), ], ), diff --git a/lib/ui/views/airdrop/layouts/airdrop_participate_sheet.dart b/lib/ui/views/airdrop/layouts/airdrop_participate_sheet.dart index 61400db0c..583d38972 100755 --- a/lib/ui/views/airdrop/layouts/airdrop_participate_sheet.dart +++ b/lib/ui/views/airdrop/layouts/airdrop_participate_sheet.dart @@ -5,6 +5,7 @@ import 'package:aewallet/ui/themes/archethic_theme.dart'; import 'package:aewallet/ui/util/ui_util.dart'; import 'package:aewallet/ui/views/airdrop/bloc/provider.dart'; import 'package:aewallet/ui/views/airdrop/bloc/state.dart'; +import 'package:aewallet/ui/views/airdrop/layouts/components/airdrop_participate_step_confirm_email.dart'; import 'package:aewallet/ui/views/airdrop/layouts/components/airdrop_participate_step_congrats.dart'; import 'package:aewallet/ui/views/airdrop/layouts/components/airdrop_participate_step_join_waitlist.dart'; import 'package:aewallet/ui/views/airdrop/layouts/components/airdrop_participate_step_sign.dart'; @@ -64,11 +65,13 @@ class _AirdropParticipateSheetState ? const AirdropParticipateStepWelcomeSheet() : airdropForm.airdropProcessStep == AirdropProcessStep.joinWaitlist ? const AirdropParticipateStepJoinWaitlistSheet() - : airdropForm.airdropProcessStep == AirdropProcessStep.sign - ? const AirdropParticipateStepSignSheet() - : airdropForm.airdropProcessStep == - AirdropProcessStep.supportEcosystem - ? const AirdropParticipateStepSupportEcosystemSheet() - : const AirdropParticipateStepCongratsSheet(); + : airdropForm.airdropProcessStep == AirdropProcessStep.confirmEmail + ? const AirdropParticipateStepConfirmEmailSheet() + : airdropForm.airdropProcessStep == AirdropProcessStep.sign + ? const AirdropParticipateStepSignSheet() + : airdropForm.airdropProcessStep == + AirdropProcessStep.supportEcosystem + ? const AirdropParticipateStepSupportEcosystemSheet() + : const AirdropParticipateStepCongratsSheet(); } } diff --git a/lib/ui/views/airdrop/layouts/components/airdrop_banner.dart b/lib/ui/views/airdrop/layouts/components/airdrop_banner.dart index 66bab9254..c2f63a8db 100644 --- a/lib/ui/views/airdrop/layouts/components/airdrop_banner.dart +++ b/lib/ui/views/airdrop/layouts/components/airdrop_banner.dart @@ -4,6 +4,7 @@ import 'package:aewallet/main.dart'; import 'package:aewallet/modules/aeswap/ui/views/util/app_styles.dart'; import 'package:aewallet/ui/views/airdrop/layouts/airdrop_dashboard_sheet.dart'; import 'package:aewallet/ui/views/airdrop/layouts/airdrop_participate_sheet.dart'; +import 'package:aewallet/ui/views/airdrop/layouts/components/airdrop_participants_count.dart'; import 'package:archethic_dapp_framework_flutter/archethic_dapp_framework_flutter.dart' as aedappfm; import 'package:flutter/material.dart'; @@ -34,34 +35,39 @@ class AirdropBanner extends ConsumerWidget { Widget _buildAirdropOk(BuildContext context) { final localizations = AppLocalizations.of(context)!; - final bannerTextStyle = - AppTextStyles.bodyLarge(context).copyWith(fontSize: 14); + final titleTextStyle = AppTextStyles.bodyLarge(context).copyWith( + fontWeight: FontWeight.bold, + fontSize: 18, + ); return Padding( padding: const EdgeInsets.only(top: 20), - child: _buildBannerContainer( - context, - height: 40, - child: Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Text( - localizations.airdropBannerTitle, - style: bannerTextStyle, - textAlign: TextAlign.center, - ), - const SizedBox(width: 10), - InkWell( - onTap: () async { - await context.push(AirdropDashboardSheet.routerPage); - }, - child: const Icon( - Icons.arrow_forward_ios, - color: Colors.white70, - size: 14, - ), + child: InkWell( + onTap: () async { + await context.push(AirdropDashboardSheet.routerPage); + }, + child: _buildBannerContainer( + context, + height: 60, + child: SizedBox( + height: 60, + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text( + localizations.airdropBannerTitle, + style: titleTextStyle, + textAlign: TextAlign.center, + ), + const SizedBox(width: 10), + const Icon( + Icons.arrow_forward_ios, + color: Colors.white70, + size: 14, + ), + ], ), - ], + ), ), ), ); @@ -81,13 +87,17 @@ class AirdropBanner extends ConsumerWidget { padding: const EdgeInsets.only(top: 20), child: _buildBannerContainer( context, - height: 190, + height: 230, child: Stack( alignment: Alignment.topRight, children: [ Column( mainAxisAlignment: MainAxisAlignment.center, children: [ + const AirdropParticipantsCount(), + const SizedBox( + height: 10, + ), Text( localizations.airdropBannerNewTitle, style: titleTextStyle, diff --git a/lib/ui/views/airdrop/layouts/components/airdrop_bloc_info.dart b/lib/ui/views/airdrop/layouts/components/airdrop_bloc_info.dart index abf1ef1de..cc2e1faa0 100644 --- a/lib/ui/views/airdrop/layouts/components/airdrop_bloc_info.dart +++ b/lib/ui/views/airdrop/layouts/components/airdrop_bloc_info.dart @@ -1,5 +1,5 @@ -import 'package:aewallet/application/airdrop/airdrop.dart'; import 'package:aewallet/modules/aeswap/ui/views/util/app_styles.dart'; +import 'package:aewallet/ui/views/airdrop/layouts/components/airdrop_participants_count.dart'; import 'package:archethic_dapp_framework_flutter/archethic_dapp_framework_flutter.dart' as aedappfm; import 'package:flutter/material.dart'; @@ -14,7 +14,6 @@ class AirdropBlocInfo extends ConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) { final localizations = AppLocalizations.of(context)!; - final airdropCountAsync = ref.watch(airdropCountProvider); final boldBodyLarge = AppTextStyles.bodyLarge(context).copyWith( fontWeight: FontWeight.bold, @@ -23,7 +22,6 @@ class AirdropBlocInfo extends ConsumerWidget { AppTextStyles.bodyLargeSecondaryColor(context).copyWith( fontWeight: FontWeight.bold, ); - final bodyMedium = AppTextStyles.bodyMedium(context); final bodyMediumSecondary = AppTextStyles.bodyMediumSecondaryColor(context); return LayoutBuilder( @@ -74,30 +72,7 @@ class AirdropBlocInfo extends ConsumerWidget { ], ), const SizedBox(height: 10), - Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Text( - localizations - .airdropParticipateStepWelcomeCardParticipantsCount, - style: bodyMedium, - ), - airdropCountAsync.when( - data: (data) => Text( - data != null ? '$data' : '?', - style: bodyMediumSecondary, - ), - error: (_, __) => Text( - '?', - style: bodyMediumSecondary, - ), - loading: () => Text( - '', - style: bodyMediumSecondary, - ), - ), - ], - ), + const AirdropParticipantsCount(), ], ), ], diff --git a/lib/ui/views/airdrop/layouts/components/airdrop_checkbox_confirm_not_multiple_registrations.dart b/lib/ui/views/airdrop/layouts/components/airdrop_checkbox_confirm_not_multiple_registrations.dart index 963a9219f..36f47309a 100644 --- a/lib/ui/views/airdrop/layouts/components/airdrop_checkbox_confirm_not_multiple_registrations.dart +++ b/lib/ui/views/airdrop/layouts/components/airdrop_checkbox_confirm_not_multiple_registrations.dart @@ -1,6 +1,6 @@ import 'package:aewallet/modules/aeswap/ui/views/util/app_styles.dart'; -import 'package:aewallet/ui/views/airdrop/bloc/provider.dart'; import 'package:aewallet/ui/util/custom_checkbox.dart'; +import 'package:aewallet/ui/views/airdrop/bloc/provider.dart'; import 'package:flutter/material.dart'; import 'package:flutter_gen/gen_l10n/localizations.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; diff --git a/lib/ui/views/airdrop/layouts/components/airdrop_checkbox_confirm_only_one_airdrop.dart b/lib/ui/views/airdrop/layouts/components/airdrop_checkbox_confirm_only_one_airdrop.dart index ae2d2e60d..8d66ad46d 100644 --- a/lib/ui/views/airdrop/layouts/components/airdrop_checkbox_confirm_only_one_airdrop.dart +++ b/lib/ui/views/airdrop/layouts/components/airdrop_checkbox_confirm_only_one_airdrop.dart @@ -1,6 +1,6 @@ import 'package:aewallet/modules/aeswap/ui/views/util/app_styles.dart'; -import 'package:aewallet/ui/views/airdrop/bloc/provider.dart'; import 'package:aewallet/ui/util/custom_checkbox.dart'; +import 'package:aewallet/ui/views/airdrop/bloc/provider.dart'; import 'package:flutter/material.dart'; import 'package:flutter_gen/gen_l10n/localizations.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; diff --git a/lib/ui/views/airdrop/layouts/components/airdrop_checkbox_confirm_privacy_policy.dart b/lib/ui/views/airdrop/layouts/components/airdrop_checkbox_confirm_privacy_policy.dart index 27a54b293..bb54ffdb2 100644 --- a/lib/ui/views/airdrop/layouts/components/airdrop_checkbox_confirm_privacy_policy.dart +++ b/lib/ui/views/airdrop/layouts/components/airdrop_checkbox_confirm_privacy_policy.dart @@ -1,6 +1,6 @@ import 'package:aewallet/modules/aeswap/ui/views/util/app_styles.dart'; -import 'package:aewallet/ui/views/airdrop/bloc/provider.dart'; import 'package:aewallet/ui/util/custom_checkbox.dart'; +import 'package:aewallet/ui/views/airdrop/bloc/provider.dart'; import 'package:flutter/material.dart'; import 'package:flutter_gen/gen_l10n/localizations.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; diff --git a/lib/ui/views/airdrop/layouts/components/airdrop_lp_current_value.dart b/lib/ui/views/airdrop/layouts/components/airdrop_lp_current_value.dart index 3f42b421a..20d16d228 100644 --- a/lib/ui/views/airdrop/layouts/components/airdrop_lp_current_value.dart +++ b/lib/ui/views/airdrop/layouts/components/airdrop_lp_current_value.dart @@ -3,11 +3,11 @@ import 'package:aewallet/modules/aeswap/application/session/provider.dart'; import 'package:aewallet/modules/aeswap/application/session/state.dart'; import 'package:aewallet/modules/aeswap/ui/views/util/app_styles.dart'; import 'package:aewallet/ui/views/aeswap_earn/bloc/provider.dart'; +import 'package:archethic_dapp_framework_flutter/archethic_dapp_framework_flutter.dart' + as aedappfm; import 'package:flutter/material.dart'; import 'package:flutter_gen/gen_l10n/localizations.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; -import 'package:archethic_dapp_framework_flutter/archethic_dapp_framework_flutter.dart' - as aedappfm; class AirdropLPCurrentValue extends ConsumerWidget { const AirdropLPCurrentValue({super.key}); @@ -16,7 +16,9 @@ class AirdropLPCurrentValue extends ConsumerWidget { Widget build(BuildContext context, WidgetRef ref) { final farmLock = ref.watch(farmLockFormFarmLockProvider).value; if (farmLock == null || farmLock.lpTokenPair == null) { - return const SizedBox.shrink(); + return const SizedBox( + height: 20, + ); } final localizations = AppLocalizations.of(context)!; @@ -53,7 +55,9 @@ class AirdropLPCurrentValue extends ConsumerWidget { ), ); } - return const SizedBox.shrink(); + return const SizedBox( + height: 20, + ); }, ); } diff --git a/lib/ui/views/airdrop/layouts/components/airdrop_participants_count.dart b/lib/ui/views/airdrop/layouts/components/airdrop_participants_count.dart new file mode 100644 index 000000000..761456f99 --- /dev/null +++ b/lib/ui/views/airdrop/layouts/components/airdrop_participants_count.dart @@ -0,0 +1,42 @@ +import 'package:aewallet/application/airdrop/airdrop.dart'; +import 'package:aewallet/modules/aeswap/ui/views/util/app_styles.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_gen/gen_l10n/localizations.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; + +class AirdropParticipantsCount extends ConsumerWidget { + const AirdropParticipantsCount({ + super.key, + }); + + @override + Widget build(BuildContext context, WidgetRef ref) { + final localizations = AppLocalizations.of(context)!; + final airdropCountAsync = ref.watch(airdropCountProvider); + final bodyMedium = AppTextStyles.bodyMedium(context); + final bodyMediumSecondary = AppTextStyles.bodyMediumSecondaryColor(context); + return Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text( + localizations.airdropParticipateStepWelcomeCardParticipantsCount, + style: bodyMedium, + ), + airdropCountAsync.when( + data: (data) => Text( + data != null ? '$data' : '?', + style: bodyMediumSecondary, + ), + error: (_, __) => Text( + '?', + style: bodyMediumSecondary, + ), + loading: () => Text( + '', + style: bodyMediumSecondary, + ), + ), + ], + ); + } +} diff --git a/lib/ui/views/airdrop/layouts/components/airdrop_participate_step_confirm_email.dart b/lib/ui/views/airdrop/layouts/components/airdrop_participate_step_confirm_email.dart new file mode 100644 index 000000000..f06e5c1ff --- /dev/null +++ b/lib/ui/views/airdrop/layouts/components/airdrop_participate_step_confirm_email.dart @@ -0,0 +1,152 @@ +import 'package:aewallet/application/account/accounts_notifier.dart'; +import 'package:aewallet/modules/aeswap/ui/views/util/app_styles.dart'; +import 'package:aewallet/ui/themes/archethic_theme.dart'; +import 'package:aewallet/ui/util/dimens.dart'; +import 'package:aewallet/ui/views/airdrop/bloc/provider.dart'; +import 'package:aewallet/ui/views/airdrop/bloc/state.dart'; +import 'package:aewallet/ui/views/airdrop/layouts/components/airdrop_stepper.dart'; +import 'package:aewallet/ui/views/main/components/sheet_appbar.dart'; +import 'package:aewallet/ui/widgets/components/app_button_tiny.dart'; +import 'package:aewallet/ui/widgets/components/sheet_skeleton.dart'; +import 'package:aewallet/ui/widgets/components/sheet_skeleton_interface.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_gen/gen_l10n/localizations.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; + +class AirdropParticipateStepConfirmEmailSheet extends ConsumerStatefulWidget { + const AirdropParticipateStepConfirmEmailSheet({ + super.key, + }); + + @override + ConsumerState createState() => + _AirdropParticipateStepJoinWaitlistSheetState(); +} + +class _AirdropParticipateStepJoinWaitlistSheetState + extends ConsumerState + implements SheetSkeletonInterface { + @override + Widget build( + BuildContext context, + ) { + final accountSelected = ref.watch( + accountsNotifierProvider.select( + (accounts) => accounts.valueOrNull?.selectedAccount, + ), + ); + + if (accountSelected == null) return const SizedBox(); + + return SheetSkeleton( + appBar: getAppBar(context, ref), + floatingActionButton: getFloatingActionButton(context, ref), + sheetContent: getSheetContent(context, ref), + ); + } + + @override + Widget getFloatingActionButton(BuildContext context, WidgetRef ref) { + final localizations = AppLocalizations.of(context)!; + final airdropForm = ref.watch(airdropFormNotifierProvider); + return Row( + children: [ + AppButtonTinyConnectivity( + localizations.airdropParticipateStepWaitlistBtn, + Dimens.buttonBottomDimens, + onPressed: () async { + ref + .read(airdropFormNotifierProvider.notifier) + .setAirdropProcessStep(AirdropProcessStep.sign); + }, + disabled: !airdropForm.isItemsConfirmed, + ), + ], + ); + } + + @override + PreferredSizeWidget getAppBar(BuildContext context, WidgetRef ref) { + final localizations = AppLocalizations.of(context)!; + return SheetAppBar( + title: localizations.airdropParticipateTitle, + widgetLeft: BackButton( + key: const Key('back'), + color: ArchethicTheme.text, + onPressed: () { + ref + .read(airdropFormNotifierProvider.notifier) + .setAirdropProcessStep(AirdropProcessStep.joinWaitlist); + }, + ), + ); + } + + @override + Widget getSheetContent(BuildContext context, WidgetRef ref) { + final localizations = AppLocalizations.of(context)!; + final airdropForm = ref.read(airdropFormNotifierProvider); + return SingleChildScrollView( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const AirdropStepper(), + Text( + localizations.airdropParticipateStepConfirmEmailTitle, + style: AppTextStyles.bodyLarge(context) + .copyWith(fontWeight: FontWeight.bold), + ), + const SizedBox(height: 20), + Text( + localizations.airdropParticipateStepConfirmEmailDesc1, + style: AppTextStyles.bodyMediumWithOpacity(context), + ), + const SizedBox(height: 20), + Text( + airdropForm.mailAddress ?? '?', + style: AppTextStyles.bodyMedium(context) + .copyWith(fontWeight: FontWeight.bold), + ), + const SizedBox(height: 30), + Text( + localizations.airdropParticipateStepConfirmEmailDesc2, + style: AppTextStyles.bodyMediumWithOpacity(context), + ), + InkWell( + child: Text( + localizations.airdropParticipateStepConfirmEmailDesc3, + style: AppTextStyles.bodyMedium(context) + .copyWith(decoration: TextDecoration.underline), + ), + ), + const SizedBox(height: 30), + Row( + children: [ + Text( + '${localizations.airdropParticipateStepConfirmEmailDesc4} ', + style: AppTextStyles.bodyMediumWithOpacity(context), + ), + InkWell( + onTap: () => ref + .read(airdropFormNotifierProvider.notifier) + .setAirdropProcessStep(AirdropProcessStep.joinWaitlist), + child: Text( + localizations.airdropParticipateStepConfirmEmailDesc5, + style: AppTextStyles.bodyMedium(context) + .copyWith(decoration: TextDecoration.underline), + ), + ), + ], + ), + const SizedBox(height: 30), + Text( + localizations.airdropParticipateStepConfirmEmailDesc6, + style: AppTextStyles.bodyMediumWithOpacity(context) + .copyWith(fontWeight: FontWeight.bold), + ), + const SizedBox(height: 20), + ], + ), + ); + } +} diff --git a/lib/ui/views/airdrop/layouts/components/airdrop_participate_step_congrats.dart b/lib/ui/views/airdrop/layouts/components/airdrop_participate_step_congrats.dart index bc8199778..71c53afac 100644 --- a/lib/ui/views/airdrop/layouts/components/airdrop_participate_step_congrats.dart +++ b/lib/ui/views/airdrop/layouts/components/airdrop_participate_step_congrats.dart @@ -1,9 +1,12 @@ import 'package:aewallet/application/account/accounts_notifier.dart'; +import 'package:aewallet/application/airdrop/airdrop.dart'; import 'package:aewallet/application/settings/settings.dart'; import 'package:aewallet/modules/aeswap/ui/views/util/app_styles.dart'; import 'package:aewallet/ui/themes/archethic_theme.dart'; import 'package:aewallet/ui/util/dimens.dart'; import 'package:aewallet/ui/views/airdrop/layouts/components/airdrop_lp_current_value.dart'; +import 'package:aewallet/ui/views/airdrop/layouts/components/airdrop_personal_multiplier.dart'; +import 'package:aewallet/ui/views/airdrop/layouts/components/airdrop_personal_rewards.dart'; import 'package:aewallet/ui/views/airdrop/layouts/components/airdrop_step_tab.dart'; import 'package:aewallet/ui/views/main/bloc/providers.dart'; import 'package:aewallet/ui/views/main/components/sheet_appbar.dart'; @@ -88,6 +91,17 @@ class _AirdropParticipateStepCongratsSheetState @override Widget getSheetContent(BuildContext context, WidgetRef ref) { final localizations = AppLocalizations.of(context)!; + final airdropPersonalMultiplierAsync = + ref.watch(airdropPersonalMultiplierProvider); + int? personalMultiplier; + airdropPersonalMultiplierAsync.when( + data: (data) { + personalMultiplier = data; + }, + error: (_, __) {}, + loading: () {}, + ); + return SingleChildScrollView( child: Column( crossAxisAlignment: CrossAxisAlignment.start, @@ -98,9 +112,19 @@ class _AirdropParticipateStepCongratsSheetState .copyWith(fontWeight: FontWeight.bold), ), const SizedBox(height: 20), + Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + AirdropPersonalMultiplier( + personalMultiplier: personalMultiplier, + ), + const AirdropPersonalRewards(), + ], + ), + const SizedBox(height: 20), const AirdropLPCurrentValue(), const SizedBox(height: 10), - const AirdropStepTab(), + AirdropStepTab(personalMultiplier: personalMultiplier), const SizedBox(height: 20), ], ), diff --git a/lib/ui/views/airdrop/layouts/components/airdrop_participate_step_join_waitlist.dart b/lib/ui/views/airdrop/layouts/components/airdrop_participate_step_join_waitlist.dart index 33d481fb5..540c0ea91 100644 --- a/lib/ui/views/airdrop/layouts/components/airdrop_participate_step_join_waitlist.dart +++ b/lib/ui/views/airdrop/layouts/components/airdrop_participate_step_join_waitlist.dart @@ -7,6 +7,7 @@ import 'package:aewallet/ui/views/airdrop/bloc/state.dart'; import 'package:aewallet/ui/views/airdrop/layouts/components/airdrop_checkbox_confirm_not_multiple_registrations.dart'; import 'package:aewallet/ui/views/airdrop/layouts/components/airdrop_checkbox_confirm_only_one_airdrop.dart'; import 'package:aewallet/ui/views/airdrop/layouts/components/airdrop_checkbox_confirm_privacy_policy.dart'; +import 'package:aewallet/ui/views/airdrop/layouts/components/airdrop_stepper.dart'; import 'package:aewallet/ui/views/airdrop/layouts/components/airdrop_textfield_mail.dart'; import 'package:aewallet/ui/views/main/components/sheet_appbar.dart'; import 'package:aewallet/ui/widgets/components/app_button_tiny.dart'; @@ -60,7 +61,7 @@ class _AirdropParticipateStepJoinWaitlistSheetState onPressed: () async { ref .read(airdropFormNotifierProvider.notifier) - .setAirdropProcessStep(AirdropProcessStep.sign); + .setAirdropProcessStep(AirdropProcessStep.confirmEmail); }, disabled: !airdropForm.isItemsConfirmed, ), @@ -92,6 +93,7 @@ class _AirdropParticipateStepJoinWaitlistSheetState child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ + const AirdropStepper(), Text( localizations.airdropParticipateStepWaitlistTitle, style: AppTextStyles.bodyLarge(context) @@ -100,7 +102,7 @@ class _AirdropParticipateStepJoinWaitlistSheetState const SizedBox(height: 20), Text( localizations.airdropParticipateStepWaitlistDesc2, - style: AppTextStyles.bodySmallWithOpacity(context), + style: AppTextStyles.bodyMediumWithOpacity(context), ), const SizedBox(height: 20), const AirdropTextFieldMail(), diff --git a/lib/ui/views/airdrop/layouts/components/airdrop_participate_step_sign.dart b/lib/ui/views/airdrop/layouts/components/airdrop_participate_step_sign.dart index fae87a42f..ca4309848 100644 --- a/lib/ui/views/airdrop/layouts/components/airdrop_participate_step_sign.dart +++ b/lib/ui/views/airdrop/layouts/components/airdrop_participate_step_sign.dart @@ -4,6 +4,7 @@ import 'package:aewallet/ui/themes/archethic_theme.dart'; import 'package:aewallet/ui/util/dimens.dart'; import 'package:aewallet/ui/views/airdrop/bloc/provider.dart'; import 'package:aewallet/ui/views/airdrop/bloc/state.dart'; +import 'package:aewallet/ui/views/airdrop/layouts/components/airdrop_stepper.dart'; import 'package:aewallet/ui/views/main/components/sheet_appbar.dart'; import 'package:aewallet/ui/widgets/components/app_button_tiny.dart'; import 'package:aewallet/ui/widgets/components/sheet_skeleton.dart'; @@ -92,6 +93,7 @@ class _AirdropParticipateStepSignSheetState child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ + const AirdropStepper(), Text( localizations.airdropParticipateStepSignTitle, style: AppTextStyles.bodyLarge(context) diff --git a/lib/ui/views/airdrop/layouts/components/airdrop_participate_step_support_ecosystem.dart b/lib/ui/views/airdrop/layouts/components/airdrop_participate_step_support_ecosystem.dart index fb33f41bd..d890aa569 100644 --- a/lib/ui/views/airdrop/layouts/components/airdrop_participate_step_support_ecosystem.dart +++ b/lib/ui/views/airdrop/layouts/components/airdrop_participate_step_support_ecosystem.dart @@ -1,4 +1,5 @@ import 'package:aewallet/application/account/accounts_notifier.dart'; +import 'package:aewallet/application/airdrop/airdrop.dart'; import 'package:aewallet/modules/aeswap/ui/views/util/app_styles.dart'; import 'package:aewallet/ui/themes/archethic_theme.dart'; import 'package:aewallet/ui/util/dimens.dart'; @@ -7,6 +8,7 @@ import 'package:aewallet/ui/views/airdrop/bloc/provider.dart'; import 'package:aewallet/ui/views/airdrop/bloc/state.dart'; import 'package:aewallet/ui/views/airdrop/layouts/components/airdrop_lp_current_value.dart'; import 'package:aewallet/ui/views/airdrop/layouts/components/airdrop_step_tab.dart'; +import 'package:aewallet/ui/views/airdrop/layouts/components/airdrop_stepper.dart'; import 'package:aewallet/ui/views/main/components/sheet_appbar.dart'; import 'package:aewallet/ui/widgets/components/app_button_tiny.dart'; import 'package:aewallet/ui/widgets/components/sheet_skeleton.dart'; @@ -88,10 +90,23 @@ class _AirdropParticipateStepSupportEcosystemSheetState Widget getSheetContent(BuildContext context, WidgetRef ref) { final localizations = AppLocalizations.of(context)!; final farmLock = ref.watch(farmLockFormFarmLockProvider).valueOrNull; + + final airdropPersonalMultiplierAsync = + ref.watch(airdropPersonalMultiplierProvider); + int? personalMultiplier; + airdropPersonalMultiplierAsync.when( + data: (data) { + personalMultiplier = data; + }, + error: (_, __) {}, + loading: () {}, + ); + return SingleChildScrollView( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ + const AirdropStepper(), Text( localizations.airdropParticipateStepSupportEcosystemTitle, style: AppTextStyles.bodyLarge(context) @@ -123,7 +138,8 @@ class _AirdropParticipateStepSupportEcosystemSheetState const SizedBox(height: 20), const AirdropLPCurrentValue(), const SizedBox(height: 10), - const AirdropStepTab(), + AirdropStepTab(personalMultiplier: personalMultiplier), + const SizedBox(height: 90), ], ), ); diff --git a/lib/ui/views/airdrop/layouts/components/airdrop_personal_multiplier.dart b/lib/ui/views/airdrop/layouts/components/airdrop_personal_multiplier.dart new file mode 100644 index 000000000..a537d4b09 --- /dev/null +++ b/lib/ui/views/airdrop/layouts/components/airdrop_personal_multiplier.dart @@ -0,0 +1,50 @@ +import 'package:aewallet/modules/aeswap/ui/views/util/app_styles.dart'; +import 'package:aewallet/ui/themes/archethic_theme_base.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_gen/gen_l10n/localizations.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; + +class AirdropPersonalMultiplier extends ConsumerWidget { + const AirdropPersonalMultiplier({ + required this.personalMultiplier, + super.key, + }); + + final int? personalMultiplier; + + @override + Widget build(BuildContext context, WidgetRef ref) { + final localizations = AppLocalizations.of(context)!; + + return Container( + height: 100, + padding: const EdgeInsets.only(top: 10, bottom: 10, left: 30, right: 30), + decoration: BoxDecoration( + border: Border.all( + color: ArchethicThemeBase.palePurpleBorder, + ), + borderRadius: BorderRadius.circular(20), + color: Colors.black, + ), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text( + '${personalMultiplier ?? 0}x', + style: AppTextStyles.bodyLarge(context).copyWith( + fontSize: 24, + fontWeight: FontWeight.bold, + ), + ), + const SizedBox( + height: 5, + ), + Text( + localizations.airdropPersonalMultiplier, + style: AppTextStyles.bodyMediumWithOpacity(context), + ), + ], + ), + ); + } +} diff --git a/lib/ui/views/airdrop/layouts/components/airdrop_personal_rewards.dart b/lib/ui/views/airdrop/layouts/components/airdrop_personal_rewards.dart new file mode 100644 index 000000000..16eb4c9f2 --- /dev/null +++ b/lib/ui/views/airdrop/layouts/components/airdrop_personal_rewards.dart @@ -0,0 +1,45 @@ +import 'package:aewallet/modules/aeswap/ui/views/util/app_styles.dart'; +import 'package:aewallet/ui/themes/archethic_theme_base.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_gen/gen_l10n/localizations.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; + +class AirdropPersonalRewards extends ConsumerWidget { + const AirdropPersonalRewards({super.key}); + + @override + Widget build(BuildContext context, WidgetRef ref) { + final localizations = AppLocalizations.of(context)!; + + return Container( + height: 100, + padding: const EdgeInsets.only(top: 10, bottom: 10, left: 30, right: 30), + decoration: BoxDecoration( + border: Border.all( + color: ArchethicThemeBase.palePurpleBorder, + ), + borderRadius: BorderRadius.circular(20), + color: Colors.black, + ), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text( + r'$2,570', + style: AppTextStyles.bodyLarge(context).copyWith( + fontSize: 24, + fontWeight: FontWeight.bold, + ), + ), + const SizedBox( + height: 5, + ), + Text( + localizations.airdropPersonalValue, + style: AppTextStyles.bodyMediumWithOpacity(context), + ), + ], + ), + ); + } +} diff --git a/lib/ui/views/airdrop/layouts/components/airdrop_step_tab.dart b/lib/ui/views/airdrop/layouts/components/airdrop_step_tab.dart index 942234501..bb89b2808 100644 --- a/lib/ui/views/airdrop/layouts/components/airdrop_step_tab.dart +++ b/lib/ui/views/airdrop/layouts/components/airdrop_step_tab.dart @@ -5,9 +5,9 @@ import 'package:flutter_gen/gen_l10n/localizations.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; class AirdropStepTab extends ConsumerWidget { - const AirdropStepTab({this.currentStep, super.key}); + const AirdropStepTab({required this.personalMultiplier, super.key}); - final int? currentStep; + final int? personalMultiplier; @override Widget build(BuildContext context, WidgetRef ref) { @@ -70,7 +70,8 @@ class AirdropStepTab extends ConsumerWidget { for (final row in data) TableRow( decoration: BoxDecoration( - color: currentStep != null && currentStep == row['Step'] + color: personalMultiplier != null && + '${personalMultiplier}x' == row['Multiplier'] ? ArchethicThemeBase.raspberry500.withOpacity(0.5) : row['Step'] % 2 == 0 ? ArchethicThemeBase.palePurpleBackground diff --git a/lib/ui/views/airdrop/layouts/components/airdrop_stepper.dart b/lib/ui/views/airdrop/layouts/components/airdrop_stepper.dart new file mode 100644 index 000000000..861235504 --- /dev/null +++ b/lib/ui/views/airdrop/layouts/components/airdrop_stepper.dart @@ -0,0 +1,73 @@ +import 'package:aewallet/modules/aeswap/ui/views/util/app_styles.dart'; +import 'package:aewallet/ui/themes/archethic_theme_base.dart'; +import 'package:aewallet/ui/views/airdrop/bloc/provider.dart'; +import 'package:aewallet/ui/views/airdrop/bloc/state.dart'; +import 'package:easy_stepper/easy_stepper.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; + +class AirdropStepper extends ConsumerWidget { + const AirdropStepper({super.key}); + + @override + Widget build(BuildContext context, WidgetRef ref) { + final airdropForm = ref.watch(airdropFormNotifierProvider); + final activeStep = airdropForm.airdropProcessStep == + AirdropProcessStep.joinWaitlist + ? 1 + : airdropForm.airdropProcessStep == AirdropProcessStep.confirmEmail || + airdropForm.airdropProcessStep == AirdropProcessStep.sign + ? 2 + : 3; + return SizedBox( + height: 90, + child: EasyStepper( + activeStep: activeStep, + internalPadding: 0, + borderThickness: 0, + lineStyle: LineStyle( + lineLength: 50, + lineType: LineType.normal, + lineSpace: 0, + lineWidth: 20, + activeLineColor: ArchethicThemeBase.neutral800, + defaultLineColor: ArchethicThemeBase.neutral800, + unreachedLineColor: ArchethicThemeBase.neutral800, + finishedLineColor: ArchethicThemeBase.blue400, + ), + stepRadius: 28, + finishedStepBackgroundColor: Colors.transparent, + showLoadingAnimation: false, + steps: [ + EasyStep( + customStep: CircleAvatar( + radius: 20, + backgroundColor: activeStep >= 1 + ? ArchethicThemeBase.blue400 + : ArchethicThemeBase.neutral800, + child: Text('1', style: AppTextStyles.bodyLarge(context)), + ), + ), + EasyStep( + customStep: CircleAvatar( + radius: 20, + backgroundColor: activeStep >= 2 + ? ArchethicThemeBase.blue400 + : ArchethicThemeBase.neutral800, + child: Text('2', style: AppTextStyles.bodyLarge(context)), + ), + ), + EasyStep( + customStep: CircleAvatar( + radius: 20, + backgroundColor: activeStep >= 3 + ? ArchethicThemeBase.blue400 + : ArchethicThemeBase.neutral800, + child: Text('3', style: AppTextStyles.bodyLarge(context)), + ), + ), + ], + ), + ); + } +} diff --git a/pubspec.lock b/pubspec.lock index 845c60231..f52d7b949 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -430,6 +430,14 @@ packages: url: "https://pub.dev" source: hosted version: "7.0.2" + easy_stepper: + dependency: "direct main" + description: + name: easy_stepper + sha256: "63f66314a509ec690c8152a41288961fd96ba9e92ef184299f068a5e78bd16ad" + url: "https://pub.dev" + source: hosted + version: "0.8.5+1" ecdsa: dependency: transitive description: @@ -1138,6 +1146,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.3.0" + lottie: + dependency: transitive + description: + name: lottie + sha256: fa39707f36786707b01eca7626d2c16c32aa603b3f3a146518518458847dc127 + url: "https://pub.dev" + source: hosted + version: "3.2.0" macros: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 4beefcaee..30a39a63c 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -72,6 +72,9 @@ dependencies: # Get infos about the device device_info_plus: ^10.1.2 + # A fully customizable, beautiful and easy to use stepper widget. It help you to show or collect information from users using organized steps. + easy_stepper: ^0.8.5+1 + # A new flutter package to display notifications on top of the screen, full customizable with built-in themes elegant_notification: ^2.1.0 diff --git a/untranslated_messages.txt b/untranslated_messages.txt index 11edf3b00..5669dd165 100644 --- a/untranslated_messages.txt +++ b/untranslated_messages.txt @@ -20,6 +20,13 @@ "airdropParticipateStepWaitlistDesc2", "airdropParticipateStepWaitlistInputField", "airdropParticipateStepWaitlistBtn", + "airdropParticipateStepConfirmEmailTitle", + "airdropParticipateStepConfirmEmailDesc1", + "airdropParticipateStepConfirmEmailDesc2", + "airdropParticipateStepConfirmEmailDesc3", + "airdropParticipateStepConfirmEmailDesc4", + "airdropParticipateStepConfirmEmailDesc5", + "airdropParticipateStepConfirmEmailDesc6", "airdropParticipateStepSupportEcosystemTitle", "airdropParticipateStepSupportEcosystemDesc1", "airdropParticipateStepSupportEcosystemDesc2",