From a6e8b9d07073a247011df14174eff796acb0b401 Mon Sep 17 00:00:00 2001 From: Polyanka1 Date: Mon, 13 Jul 2026 15:46:34 +0300 Subject: [PATCH] fix payment card change. fix adding a new payment card --- lib/di/service_locator.dart | 2 +- .../sheet/payment_method_sheet.dart | 116 +++--------------- .../components/sheet/tariff_sheet.dart | 1 - lib/presentation/components/side_menu.dart | 2 +- .../event/payment_method_sheet_event.dart | 4 +- .../screens/edit_profile_screen.dart | 3 +- .../screens/payment_confirm_screen.dart | 2 +- .../screens/send_photo_screen.dart | 16 +-- lib/presentation/screens/top_up_screen.dart | 2 +- .../viewmodel/payment_method_sheet_bloc.dart | 51 ++++---- 10 files changed, 55 insertions(+), 144 deletions(-) diff --git a/lib/di/service_locator.dart b/lib/di/service_locator.dart index 63f79b3..162a7e7 100644 --- a/lib/di/service_locator.dart +++ b/lib/di/service_locator.dart @@ -307,7 +307,7 @@ Future setupDependencies() async { getIt.registerFactory(() => VerifyCodeBloc(getIt(), getIt(), getIt())); - getIt.registerFactory(() => ProfileBloc(getIt(), getIt(), getIt())); + getIt.registerLazySingleton(() => ProfileBloc(getIt(), getIt(), getIt())); getIt.registerFactory( () => EditProfileBloc(getIt(), getIt()), diff --git a/lib/presentation/components/sheet/payment_method_sheet.dart b/lib/presentation/components/sheet/payment_method_sheet.dart index 389432c..f83a766 100644 --- a/lib/presentation/components/sheet/payment_method_sheet.dart +++ b/lib/presentation/components/sheet/payment_method_sheet.dart @@ -27,6 +27,7 @@ class PaymentMethodSheet extends StatefulWidget { class _PaymentMethodSheetState extends State { int? _selectedPaymentMethod = -2; + int? _processingCardId; // <-- Переменная для отслеживания отправленного запроса @override void initState() { @@ -36,56 +37,20 @@ class _PaymentMethodSheetState extends State { @override Widget build(BuildContext context) { - return BlocBuilder( + return BlocConsumer( + listener: (context, state) { + if (state.status == PaymentMethodSheetStatus.success && _processingCardId != null) { + final updatedCard = state.cards.cast().firstWhere( + (c) => c?.id == _processingCardId, + orElse: () => state.cards.cast().firstWhere((c) => c?.isMain == true, orElse: () => null), + ); + + _processingCardId = null; + Navigator.pop(context, updatedCard); + } + }, builder: (context, state) { - if (state.status == PaymentMethodSheetStatus.loading) { - return Align( - alignment: Alignment.bottomCenter, - child: ClipRRect( - borderRadius: const BorderRadius.vertical(top: Radius.circular(30)), - child: BackdropFilter( - filter: ImageFilter.blur(sigmaX: 20, sigmaY: 20), - child: Container( - height: 450, - decoration: BoxDecoration( - color: const Color(0x00000032).withOpacity(0.6), - borderRadius: const BorderRadius.vertical(top: Radius.circular(30)), - ), - child: const Center( - child: CircularProgressIndicator(color: Colors.white), - ), - ), - ), - ), - ); - } - - if (state.status == PaymentMethodSheetStatus.failure) { - return Align( - alignment: Alignment.bottomCenter, - child: ClipRRect( - borderRadius: const BorderRadius.vertical(top: Radius.circular(30)), - child: BackdropFilter( - filter: ImageFilter.blur(sigmaX: 20, sigmaY: 20), - child: Container( - height: 450, - decoration: BoxDecoration( - color: const Color(0x00000032).withOpacity(0.6), - borderRadius: const BorderRadius.vertical(top: Radius.circular(30)), - ), - child: Center( - child: Text( - state.errorMessage ?? 'Ошибка загрузки карт', - style: const TextStyle(color: Colors.white), - ), - ), - ), - ), - ), - ); - } - if (state.status == PaymentMethodSheetStatus.success && _selectedPaymentMethod == -2) { if (widget.initialSelectedCard != null) { final initialIndex = state.cards.indexWhere( @@ -98,14 +63,6 @@ class _PaymentMethodSheetState extends State { } } - // Находим карту с isMain: true при загрузке - /*if (_selectedPaymentMethod == null) { - final mainCardIndex = state.cards.indexWhere((card) => card.isMain); - if (mainCardIndex != -1) { - _selectedPaymentMethod = mainCardIndex; - } - }*/ - return Align( alignment: Alignment.bottomCenter, child: ClipRRect( @@ -122,47 +79,6 @@ class _PaymentMethodSheetState extends State { child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - Padding( - padding: const EdgeInsets.symmetric(horizontal: 20), - child: Row( - children: [ - GestureDetector( - onTap: () => Navigator.pop(context), - child: Row( - children: [ - Icon( - Icons.arrow_back_ios_sharp, - color: const Color(0x99FFFFFF), - size: 20, - ), - Icon( - Icons.arrow_back_ios_sharp, - color: const Color(0x66FFFFFF), - size: 20, - ), - Icon( - Icons.arrow_back_ios_sharp, - color: const Color(0x22FFFFFF), - size: 20, - ), - ], - ), - ), - const SizedBox(width: 12), - Expanded( - child: Text( - 'Выберите способ оплаты', - style: const TextStyle( - color: Colors.white, - fontSize: 16, - fontWeight: FontWeight.w600, - ), - overflow: TextOverflow.ellipsis, - ), - ), - ], - ), - ), const SizedBox(height: 20), @@ -198,13 +114,14 @@ class _PaymentMethodSheetState extends State { onTap: () async { setState(() { _selectedPaymentMethod = index; + _processingCardId = card.id; }); + // Отправляем событие в Блок context.read().add( SelectPaymentCardRequested(card), ); - Navigator.pop(context, card); }, ), ); @@ -223,8 +140,7 @@ class _PaymentMethodSheetState extends State { color: Colors.transparent, child: InkWell( onTap: () { - Navigator.pop(context); - context.go('/home/payment-methods/add-card'); + context.read().add(AddPaymentCardRequested()); }, borderRadius: BorderRadius.circular(24), child: Center( diff --git a/lib/presentation/components/sheet/tariff_sheet.dart b/lib/presentation/components/sheet/tariff_sheet.dart index 326ec4a..9a11728 100644 --- a/lib/presentation/components/sheet/tariff_sheet.dart +++ b/lib/presentation/components/sheet/tariff_sheet.dart @@ -324,7 +324,6 @@ class _TariffSheetState extends State { getIt(), getIt(), getIt(), - )..add(PaymentMethodSheetStarted()), child: PaymentMethodSheet( initialSelectedCard: state.useBalance ? null : state.selectedCard, diff --git a/lib/presentation/components/side_menu.dart b/lib/presentation/components/side_menu.dart index 98e8bfe..2f015c2 100644 --- a/lib/presentation/components/side_menu.dart +++ b/lib/presentation/components/side_menu.dart @@ -47,7 +47,7 @@ class SideMenu extends StatelessWidget { ), const SizedBox(height: 4), Text( - 'Баланс ${state.balance} руб.', + 'Баланс ${state.balance} баллов', style: const TextStyle( color: Colors.white70, fontSize: 14, diff --git a/lib/presentation/event/payment_method_sheet_event.dart b/lib/presentation/event/payment_method_sheet_event.dart index 3af9d6e..872c67a 100644 --- a/lib/presentation/event/payment_method_sheet_event.dart +++ b/lib/presentation/event/payment_method_sheet_event.dart @@ -4,9 +4,9 @@ sealed class PaymentMethodSheetEvent {} class PaymentMethodSheetStarted extends PaymentMethodSheetEvent {} -class AddCardButtonPressed extends PaymentMethodSheetEvent {} - class SelectPaymentCardRequested extends PaymentMethodSheetEvent { final PaymentCard card; SelectPaymentCardRequested(this.card); } + +class AddPaymentCardRequested extends PaymentMethodSheetEvent {} diff --git a/lib/presentation/screens/edit_profile_screen.dart b/lib/presentation/screens/edit_profile_screen.dart index 7cb9e2b..7541c80 100644 --- a/lib/presentation/screens/edit_profile_screen.dart +++ b/lib/presentation/screens/edit_profile_screen.dart @@ -4,6 +4,7 @@ import 'package:go_router/go_router.dart'; import 'package:intl/intl.dart'; import '../../core/app_colors.dart'; +import '../../di/service_locator.dart'; import '../../domain/entities/user_profile.dart'; import '../components/custom_app_bar.dart'; import '../components/gradient_button.dart'; @@ -106,7 +107,7 @@ class _EditProfileScreenState extends State { } if (state.isSuccess) { - context.read().add(ProfileUpdated()); + getIt().add(ProfileUpdated()); context.pop(); } if (state.error != null) { diff --git a/lib/presentation/screens/payment_confirm_screen.dart b/lib/presentation/screens/payment_confirm_screen.dart index cb69ff3..893b0e2 100644 --- a/lib/presentation/screens/payment_confirm_screen.dart +++ b/lib/presentation/screens/payment_confirm_screen.dart @@ -1,10 +1,10 @@ -import 'package:be_happy/domain/usecase/add_payment_card_usecase.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:go_router/go_router.dart'; import '../../core/app_colors.dart'; import '../../di/service_locator.dart'; import '../../domain/entities/payment_card.dart'; +import '../../domain/usecase/add_payment_card_usecase.dart'; import '../../domain/usecase/get_payment_cards_usecase.dart'; import '../../domain/usecase/get_profile_usecase.dart'; import '../../domain/usecase/set_main_payment_card_usecase.dart'; diff --git a/lib/presentation/screens/send_photo_screen.dart b/lib/presentation/screens/send_photo_screen.dart index 041ff6c..d0eba69 100644 --- a/lib/presentation/screens/send_photo_screen.dart +++ b/lib/presentation/screens/send_photo_screen.dart @@ -59,14 +59,14 @@ class _SendPhotoViewState extends State { _getImage(ImageSource.camera); }, ), - ListTile( - leading: const Icon(Icons.photo_library), - title: const Text('Выбрать из галереи'), - onTap: () { - Navigator.pop(context); - _getImage(ImageSource.gallery); - }, - ), + // ListTile( + // leading: const Icon(Icons.photo_library), + // title: const Text('Выбрать из галереи'), + // onTap: () { + // Navigator.pop(context); + // _getImage(ImageSource.gallery); + // }, + // ), ListTile( leading: const Icon(Icons.cancel), title: const Text('Отмена'), diff --git a/lib/presentation/screens/top_up_screen.dart b/lib/presentation/screens/top_up_screen.dart index 657055e..3f43b2e 100644 --- a/lib/presentation/screens/top_up_screen.dart +++ b/lib/presentation/screens/top_up_screen.dart @@ -1,3 +1,4 @@ +import 'package:be_happy/domain/usecase/add_payment_card_usecase.dart'; import 'package:be_happy/presentation/viewmodel/payment_methods_bloc.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; @@ -6,7 +7,6 @@ import 'package:go_router/go_router.dart'; import '../../core/app_colors.dart'; import '../../di/service_locator.dart'; import '../../domain/entities/payment_card.dart'; -import '../../domain/usecase/add_payment_card_usecase.dart'; import '../../domain/usecase/get_payment_cards_usecase.dart'; import '../../domain/usecase/get_profile_usecase.dart'; import '../../domain/usecase/set_main_payment_card_usecase.dart'; diff --git a/lib/presentation/viewmodel/payment_method_sheet_bloc.dart b/lib/presentation/viewmodel/payment_method_sheet_bloc.dart index 6a0ef4f..05d31e7 100644 --- a/lib/presentation/viewmodel/payment_method_sheet_bloc.dart +++ b/lib/presentation/viewmodel/payment_method_sheet_bloc.dart @@ -1,5 +1,3 @@ -import 'dart:async'; - import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:url_launcher/url_launcher.dart'; @@ -12,25 +10,23 @@ import '../../domain/usecase/set_main_payment_card_usecase.dart'; import '../event/payment_method_sheet_event.dart'; import '../state/payment_method_sheet_state.dart'; -class PaymentMethodSheetBloc - extends Bloc { +class PaymentMethodSheetBloc extends Bloc { final GetPaymentCardsUsecase _getPaymentCardsUsecase; final GetProfileUseCase _getProfileUseCase; final SetMainPaymentCardUsecase _setMainPaymentCardUsecase; final AddPaymentCardUsecase _addPaymentCardUsecase; - - PaymentMethodSheetBloc(this._getPaymentCardsUsecase, - this._setMainPaymentCardUsecase, this._getProfileUseCase, - this._addPaymentCardUsecase) - : super( - PaymentMethodSheetState(status: PaymentMethodSheetStatus.initial)) { + PaymentMethodSheetBloc(this._getPaymentCardsUsecase, this._setMainPaymentCardUsecase, this._getProfileUseCase, this._addPaymentCardUsecase) + : super(PaymentMethodSheetState(status: PaymentMethodSheetStatus.initial)) { on(_onStarted); - on(_onAddCardButtonPressed); + on(_onSelectCard); + on(_onAddPaymentCardRequested); } - Future _onStarted(PaymentMethodSheetStarted event, - Emitter emit,) async { + Future _onStarted( + PaymentMethodSheetStarted event, + Emitter emit, + ) async { emit(state.copyWith(status: PaymentMethodSheetStatus.loading)); try { @@ -57,10 +53,10 @@ class PaymentMethodSheetBloc )); } } - - Future _onSelectCard(SelectPaymentCardRequested event, - Emitter emit,) async { - // Включаем локальный лоадер на шторке, либо просто ждем ответа + Future _onSelectCard( + SelectPaymentCardRequested event, + Emitter emit, + ) async { emit(state.copyWith(status: PaymentMethodSheetStatus.loading)); final result = await _setMainPaymentCardUsecase(event.card.id); @@ -73,8 +69,7 @@ class PaymentMethodSheetBloc cards: cardsResult.data ?? [], )); } else { - emit(state.copyWith(status: PaymentMethodSheetStatus.failure, - errorMessage: 'Ошибка обновления списка карт')); + emit(state.copyWith(status: PaymentMethodSheetStatus.failure, errorMessage: 'Ошибка обновления списка карт')); } } else { emit(state.copyWith( @@ -84,7 +79,6 @@ class PaymentMethodSheetBloc } } - // Выносим загрузку в отдельный метод для переиспользования Future _loadCards(Emitter emit) async { try { final result = await _getPaymentCardsUsecase(); @@ -107,8 +101,12 @@ class PaymentMethodSheetBloc } } - FutureOr _onAddCardButtonPressed(AddCardButtonPressed event, - Emitter emit) async { + Future _onAddPaymentCardRequested( + AddPaymentCardRequested event, + Emitter emit, + ) async { + emit(state.copyWith(status: PaymentMethodSheetStatus.loading)); + try { final result = await _addPaymentCardUsecase(); @@ -118,9 +116,8 @@ class PaymentMethodSheetBloc if (formUrlString != null && formUrlString.isNotEmpty) { final url = Uri.parse(formUrlString); - if (await canLaunchUrl(url) - ) { - launchUrl( + if (await canLaunchUrl(url)) { + await launchUrl( url, mode: LaunchMode.externalApplication, ); @@ -138,11 +135,9 @@ class PaymentMethodSheetBloc )); } } else if (result is Failure) { - String errorMessage = 'Ошибка при добавлении карты'; - emit(state.copyWith( status: PaymentMethodSheetStatus.failure, - errorMessage: errorMessage, + errorMessage: 'Ошибка при добавлении карты', )); } } catch (e) { -- 2.34.1