From 09a1ec0947b3eaa38ca6e942fb210951e76bef68 Mon Sep 17 00:00:00 2001 From: mso7nueh Date: Wed, 30 Jul 2025 12:34:27 +0300 Subject: [PATCH 1/8] fix: reg, verify, loaders, grey screen when like --- .../diary/presentation/bloc/diary_cubit.dart | 1 + .../diary/presentation/bloc/diary_state.dart | 1 + .../widgets/product_loader_widget.dart | 26 ++ .../widgets/products_list_widget.dart | 6 + .../profile/models/profile_model.dart | 1 + .../presentation/pages/profile_screen.dart | 16 +- .../registration_cubit.dart | 3 +- .../registration_state.dart | 1 + .../pages/registration_screen.dart | 265 ++++++++++-------- .../presentation/pages/verify_screen.dart | 21 +- .../repositories/registration_repository.dart | 56 +++- .../bloc/settings_cubit/settings_cubit.dart | 6 +- .../services/profile_service_test.dart | 1 + 13 files changed, 260 insertions(+), 144 deletions(-) create mode 100644 lib/features/diary/presentation/widgets/product_loader_widget.dart diff --git a/lib/features/diary/presentation/bloc/diary_cubit.dart b/lib/features/diary/presentation/bloc/diary_cubit.dart index 9fd27c39..1bbfbbc7 100644 --- a/lib/features/diary/presentation/bloc/diary_cubit.dart +++ b/lib/features/diary/presentation/bloc/diary_cubit.dart @@ -243,6 +243,7 @@ class DiaryCubit extends Cubit { required int quantity, int? productNutritionalValueId, }) async { + emit((state as DiaryStateLoaded).copyWith(isLoadingAddingProductInMeal: true)); await diaryRepository.addPortionToMeal( diaryId: diaryId, mealId: mealId, diff --git a/lib/features/diary/presentation/bloc/diary_state.dart b/lib/features/diary/presentation/bloc/diary_state.dart index d5e8e39d..4779e2ea 100644 --- a/lib/features/diary/presentation/bloc/diary_state.dart +++ b/lib/features/diary/presentation/bloc/diary_state.dart @@ -29,6 +29,7 @@ abstract class DiaryState with _$DiaryState { @Default(false) bool isDiaryCommented, @Default(false) bool isWakeUpAndRetireEnabled, @Default(false) bool isMoodEnabled, + @Default(false) bool isLoadingAddingProductInMeal, }) = DiaryStateLoaded; const factory DiaryState.loadedTomorrowWithDiet({ diff --git a/lib/features/diary/presentation/widgets/product_loader_widget.dart b/lib/features/diary/presentation/widgets/product_loader_widget.dart new file mode 100644 index 00000000..7b679354 --- /dev/null +++ b/lib/features/diary/presentation/widgets/product_loader_widget.dart @@ -0,0 +1,26 @@ +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; + +class ProductLoaderWidget extends StatefulWidget { + const ProductLoaderWidget({ + super.key, + }); + + @override + State createState() => _ProductLoaderWidgetState(); +} + +class _ProductLoaderWidgetState extends State { + @override + Widget build(BuildContext context) { + return ListTile( + horizontalTitleGap: 0, + contentPadding: const EdgeInsets.only(right: 24, left: 12), + title: const CupertinoActivityIndicator(), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(20), + ), + tileColor: const Color(0xFFF6FAFF), + ); + } +} diff --git a/lib/features/diary/presentation/widgets/products_list_widget.dart b/lib/features/diary/presentation/widgets/products_list_widget.dart index 13bbe7fc..6882af08 100644 --- a/lib/features/diary/presentation/widgets/products_list_widget.dart +++ b/lib/features/diary/presentation/widgets/products_list_widget.dart @@ -1,5 +1,6 @@ import 'package:eatvio_app/features/diary/presentation/bloc/diary_cubit.dart'; import 'package:eatvio_app/features/diary/presentation/bloc/diary_state.dart'; +import 'package:eatvio_app/features/diary/presentation/widgets/product_loader_widget.dart'; import 'package:eatvio_app/features/diary/presentation/widgets/product_widget.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; @@ -25,6 +26,11 @@ class _ProductsListWidgetState extends State { ProductWidget(portion: state.diary.meals[mealIndex].portions[i]), i < state.diary.meals[mealIndex].portions.length - 1 ? const SizedBox(height: 8) : const SizedBox.shrink(), ], + if (state.isLoadingAddingProductInMeal) + const Padding( + padding: EdgeInsets.only(top: 8), + child: ProductLoaderWidget(), + ), ], ); } diff --git a/lib/features/profile/models/profile_model.dart b/lib/features/profile/models/profile_model.dart index 72e91d0d..f798021f 100644 --- a/lib/features/profile/models/profile_model.dart +++ b/lib/features/profile/models/profile_model.dart @@ -14,6 +14,7 @@ abstract class ProfileModel with _$ProfileModel { @JsonKey(name: "email") required String email, @JsonKey(name: "rating_place") int? ratingPlace, @JsonKey(name: "email_verified_at") DateTime? emailVerifiedAt, + @JsonKey(name: "phone_confirmation_state") required String phoneConfirmationState, @JsonKey(name: "created_at") DateTime? createdAt, @JsonKey(name: "updated_at") DateTime? updatedAt, @JsonKey(name: "is_public_profile", fromJson: parseBool) required bool isPublicProfile, diff --git a/lib/features/profile/presentation/pages/profile_screen.dart b/lib/features/profile/presentation/pages/profile_screen.dart index 07ab1bd2..68213da5 100644 --- a/lib/features/profile/presentation/pages/profile_screen.dart +++ b/lib/features/profile/presentation/pages/profile_screen.dart @@ -138,7 +138,7 @@ class _ProfileScreenState extends State { crossAxisAlignment: CrossAxisAlignment.center, children: [ _header(state), - if (state.profile.roles.contains('consultant')) + if (state.profile.roles.contains('consultant') && state.consultantInfo != null) Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ @@ -202,10 +202,10 @@ class _ProfileScreenState extends State { ), _subscriptionsAndSubscribers(state), if (state.profile.badges.isNotEmpty) Padding(padding: const EdgeInsets.only(bottom: 16), child: _badges(state)), - if (state.profile.roles.contains('consultant')) _socialLinks(state), - if (state.profile.roles.contains('consultant')) _education(state), - if (state.profile.roles.contains('consultant')) _diplomasAndCertificates(state), - if (state.profile.roles.contains('consultant')) _activePlans(state), + if (state.profile.roles.contains('consultant') && state.consultantInfo != null) _socialLinks(state), + if (state.profile.roles.contains('consultant') && state.consultantInfo != null) _education(state), + if (state.profile.roles.contains('consultant') && state.consultantInfo != null) _diplomasAndCertificates(state), + if (state.profile.roles.contains('consultant') && state.consultantInfo != null) _activePlans(state), _blogPosts(state), ], ), @@ -216,7 +216,9 @@ class _ProfileScreenState extends State { Scaffold _myProfileScreen(ProfileStateLoaded state) { return Scaffold( backgroundColor: Colors.grey.shade200, - appBar: AppBar(), + appBar: AppBar( + toolbarHeight: widget.author == null ? 0 : null, + ), body: SingleChildScrollView( child: Column( crossAxisAlignment: CrossAxisAlignment.start, @@ -644,7 +646,7 @@ class _ProfileScreenState extends State { } SingleChildRenderObjectWidget _socialLinks(ProfileStateLoaded state) { - if (!state.profile.roles.contains('consultant')) { + if (!state.profile.roles.contains('consultant') && state.consultantInfo != null) { return const SizedBox.shrink(); } return Padding( diff --git a/lib/features/registration/presentation/bloc/registration_cubit/registration_cubit.dart b/lib/features/registration/presentation/bloc/registration_cubit/registration_cubit.dart index fa2948bc..c9426674 100644 --- a/lib/features/registration/presentation/bloc/registration_cubit/registration_cubit.dart +++ b/lib/features/registration/presentation/bloc/registration_cubit/registration_cubit.dart @@ -60,10 +60,11 @@ class RegistrationCubit extends Cubit { ), ); await TokenStorage.saveTokenInStorage(token); - AppRouter.navigatorKey.currentContext?.pushNamed('verifyEmailScreen'); await sl().registerPushToken(); + AppRouter.navigatorKey.currentContext?.replaceNamed('verifyEmailScreen'); } catch (e, st) { log(e.toString(), stackTrace: st); + emit(RegistrationState(sheet: state.sheet, error: e.toString())); } } diff --git a/lib/features/registration/presentation/bloc/registration_cubit/registration_state.dart b/lib/features/registration/presentation/bloc/registration_cubit/registration_state.dart index e4347d20..6a280864 100644 --- a/lib/features/registration/presentation/bloc/registration_cubit/registration_state.dart +++ b/lib/features/registration/presentation/bloc/registration_cubit/registration_state.dart @@ -7,5 +7,6 @@ part 'registration_state.freezed.dart'; abstract class RegistrationState with _$RegistrationState { const factory RegistrationState({ required UserRegistrationSheet sheet, + String? error, }) = _RegistrationState; } diff --git a/lib/features/registration/presentation/pages/registration_screen.dart b/lib/features/registration/presentation/pages/registration_screen.dart index 69ae62d5..86514be8 100644 --- a/lib/features/registration/presentation/pages/registration_screen.dart +++ b/lib/features/registration/presentation/pages/registration_screen.dart @@ -43,142 +43,161 @@ class _RegistrationScreenState extends State { Widget build(BuildContext context) { return BlocProvider( create: (BuildContext context) => registrationCubit, - child: BlocBuilder( - builder: (BuildContext context, RegistrationState state) { - return Scaffold( - floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat, - floatingActionButton: Row( - children: [ - Container( - height: 48, - width: MediaQuery.of(context).size.width * 0.2, - padding: const EdgeInsets.only(left: 16, right: 4), - child: FloatingActionButton.extended( - heroTag: 'backButtonRegistration', - highlightElevation: 0, - focusElevation: 0, - elevation: 0, - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(20), - ), - backgroundColor: const Color(0xFFEAF2FD), - onPressed: () async { - setState(() { - pageController.previousPage( - duration: const Duration(milliseconds: 350), - curve: Curves.easeInOut, - ); - }); - }, - label: Icon( - Icons.arrow_back_ios_new_rounded, - color: appTheme.blueA400, - ), + child: BlocListener( + listener: (context, state) { + if (state.error != null && state.error!.isNotEmpty) { + showDialog( + context: context, + builder: (context) => AlertDialog( + title: const Text('Ошибка при регистрации'), + content: Text(state.error!), + actions: [ + TextButton( + onPressed: () => Navigator.pop(context), + child: const Text('OK'), ), - ), - Container( - height: 48, - width: MediaQuery.of(context).size.width * 0.8, - padding: const EdgeInsets.only(left: 4, right: 16), - child: FloatingActionButton.extended( - heroTag: 'nextButtonRegistration', - highlightElevation: 0, - elevation: 0, - focusElevation: 0, - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(20), - ), - backgroundColor: appTheme.blueA400, - onPressed: () async { - if (await canGoNext(state, context)) { + ], + ), + ); + } + }, + child: BlocBuilder( + builder: (BuildContext context, RegistrationState state) { + return Scaffold( + floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat, + floatingActionButton: Row( + children: [ + Container( + height: 48, + width: MediaQuery.of(context).size.width * 0.2, + padding: const EdgeInsets.only(left: 16, right: 4), + child: FloatingActionButton.extended( + heroTag: 'backButtonRegistration', + highlightElevation: 0, + focusElevation: 0, + elevation: 0, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(20), + ), + backgroundColor: const Color(0xFFEAF2FD), + onPressed: () async { setState(() { - pageController.nextPage( + pageController.previousPage( duration: const Duration(milliseconds: 350), curve: Curves.easeInOut, ); }); - } - }, - label: Text( - 'Продолжить', - style: theme.textTheme.titleSmall!.copyWith(color: Colors.white), + }, + label: Icon( + Icons.arrow_back_ios_new_rounded, + color: appTheme.blueA400, + ), ), ), - ), - ], - ), - appBar: AppBar( - automaticallyImplyLeading: false, - leading: Builder( - builder: (context) => IconButton( - icon: const Icon(Icons.close_rounded), - onPressed: () => GoRouter.of(context).pop(), - ), - ), - centerTitle: true, - title: SvgPicture.asset( - ImageConstant.imgLogoEatvio, - height: 48, - fit: BoxFit.contain, - ), - actions: [ - Padding( - padding: const EdgeInsets.only(right: 16), - child: Text('шаг $step из 15'), - ), - ], - bottom: PreferredSize( - preferredSize: Size(MediaQuery.of(context).size.width, 32), - child: Padding( - padding: const EdgeInsets.all(16), - child: TweenAnimationBuilder( - duration: const Duration(milliseconds: 350), - curve: Curves.easeInOut, - tween: Tween( - begin: 1 / 15, - end: progressValue, + Container( + height: 48, + width: MediaQuery.of(context).size.width * 0.8, + padding: const EdgeInsets.only(left: 4, right: 16), + child: FloatingActionButton.extended( + heroTag: 'nextButtonRegistration', + highlightElevation: 0, + elevation: 0, + focusElevation: 0, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(20), + ), + backgroundColor: appTheme.blueA400, + onPressed: () async { + if (await canGoNext(state, context)) { + setState(() { + pageController.nextPage( + duration: const Duration(milliseconds: 350), + curve: Curves.easeInOut, + ); + }); + } + }, + label: Text( + 'Продолжить', + style: theme.textTheme.titleSmall!.copyWith(color: Colors.white), + ), ), - builder: (context, value, _) => LinearProgressIndicator( - value: value, - borderRadius: BorderRadius.circular(16), - minHeight: 8, - backgroundColor: Colors.grey.shade100, - valueColor: AlwaysStoppedAnimation(appTheme.blueA400), + ), + ], + ), + appBar: AppBar( + automaticallyImplyLeading: false, + leading: Builder( + builder: (context) => IconButton( + icon: const Icon(Icons.close_rounded), + onPressed: () => GoRouter.of(context).pop(), + ), + ), + centerTitle: true, + title: SvgPicture.asset( + ImageConstant.imgLogoEatvio, + height: 48, + fit: BoxFit.contain, + ), + actions: [ + Padding( + padding: const EdgeInsets.only(right: 16), + child: Text('шаг $step из 15'), + ), + ], + bottom: PreferredSize( + preferredSize: Size(MediaQuery.of(context).size.width, 32), + child: Padding( + padding: const EdgeInsets.all(16), + child: TweenAnimationBuilder( + duration: const Duration(milliseconds: 350), + curve: Curves.easeInOut, + tween: Tween( + begin: 1 / 15, + end: progressValue, + ), + builder: (context, value, _) => LinearProgressIndicator( + value: value, + borderRadius: BorderRadius.circular(16), + minHeight: 8, + backgroundColor: Colors.grey.shade100, + valueColor: AlwaysStoppedAnimation(appTheme.blueA400), + ), ), ), ), ), - ), - body: PageView( - physics: const NeverScrollableScrollPhysics(), - controller: pageController, - onPageChanged: (index) { - setState(() { - step = index + 1; - progressValue = step / 15; - }); - }, - children: [ - // LanguageSelectScreen(sheet: state.sheet), - PhoneScreen(sheet: state.sheet), - CredentialsScreen(sheet: state.sheet), - NameScreen(sheet: state.sheet), - GenderScreen(sheet: state.sheet), - DateOfBirthScreen(sheet: state.sheet), - CityOfLivingScreen(sheet: state.sheet), - BodyCircumferencesScreen(sheet: state.sheet), - WeightScreen(sheet: state.sheet), - HeightScreen(sheet: state.sheet), - BloodPressureScreen(sheet: state.sheet), - AllergiesScreen(sheet: state.sheet), - MedicineIntakeScreen(sheet: state.sheet), - FavoriteSportsScreen(sheet: state.sheet), - FavoriteFoodsScreen(sheet: state.sheet), - AdditionalInformationScreen(sheet: state.sheet), - ], - ), - ); - }, + body: PageView( + physics: const NeverScrollableScrollPhysics(), + controller: pageController, + onPageChanged: (index) { + setState(() { + step = index + 1; + progressValue = step / 15; + }); + }, + children: [ + // LanguageSelectScreen(sheet: state.sheet), + PhoneScreen(sheet: state.sheet), + CredentialsScreen(sheet: state.sheet), + NameScreen(sheet: state.sheet), + GenderScreen(sheet: state.sheet), + DateOfBirthScreen(sheet: state.sheet), + CityOfLivingScreen(sheet: state.sheet), + BodyCircumferencesScreen(sheet: state.sheet), + WeightScreen(sheet: state.sheet), + HeightScreen(sheet: state.sheet), + BloodPressureScreen(sheet: state.sheet), + AllergiesScreen(sheet: state.sheet), + MedicineIntakeScreen(sheet: state.sheet), + FavoriteSportsScreen(sheet: state.sheet), + FavoriteFoodsScreen(sheet: state.sheet), + AdditionalInformationScreen(sheet: state.sheet), + ], + ), + ); + }, + ), ), ); } diff --git a/lib/features/registration/presentation/pages/verify_screen.dart b/lib/features/registration/presentation/pages/verify_screen.dart index 7f8aede5..637dba5b 100644 --- a/lib/features/registration/presentation/pages/verify_screen.dart +++ b/lib/features/registration/presentation/pages/verify_screen.dart @@ -1,5 +1,6 @@ import 'package:eatvio_app/core/const.dart'; import 'package:eatvio_app/core/theme/theme_helper.dart'; +import 'package:eatvio_app/core/widgets/loader.dart'; import 'package:flutter/material.dart'; import 'package:go_router/go_router.dart'; import 'package:lottie/lottie.dart'; @@ -19,6 +20,7 @@ class VerifyScreen extends StatefulWidget { class _VerifyScreenState extends State { late final WebViewController _controller; + bool _isLoading = true; @override void initState() { @@ -27,6 +29,11 @@ class _VerifyScreenState extends State { ..setJavaScriptMode(JavaScriptMode.unrestricted) ..setNavigationDelegate( NavigationDelegate( + onPageFinished: (url) { + setState(() { + _isLoading = false; + }); + }, onNavigationRequest: (NavigationRequest request) async { if (request.url.contains('user_detailz') && !request.url.contains('change-phone-verify') || request.url.contains('email/verify')) { GoRouter.of(context).pop(); @@ -105,11 +112,17 @@ class _VerifyScreenState extends State { @override Widget build(BuildContext context) { return Scaffold( - appBar: AppBar( - toolbarHeight: 0, - ), + appBar: AppBar(toolbarHeight: 0), body: SafeArea( - child: WebViewWidget(controller: _controller), + child: Stack( + children: [ + WebViewWidget(controller: _controller), + if (_isLoading) + const Center( + child: Loader(), + ), + ], + ), ), ); } diff --git a/lib/features/registration/repositories/registration_repository.dart b/lib/features/registration/repositories/registration_repository.dart index 0c3008e0..a34bf1b0 100644 --- a/lib/features/registration/repositories/registration_repository.dart +++ b/lib/features/registration/repositories/registration_repository.dart @@ -1,7 +1,5 @@ - import 'package:dio/dio.dart'; import 'package:eatvio_app/core/locator_service.dart'; -import 'package:eatvio_app/core/utils/toasts.dart'; import 'package:eatvio_app/features/registration/models/user_registration_model.dart'; import 'package:eatvio_app/features/registration/models/location_model.dart'; import 'package:eatvio_app/features/registration/services/registration_service.dart'; @@ -14,13 +12,55 @@ class RegistrationRepository { Future tryRegister(UserRegistrationSheet sheet) async { try { final response = await registrationService.register(sheet: sheet.toJson()); - try { - return (response['token']!); - } catch (e) { - showErrorToast(response.toString()); - rethrow; + if (response.containsKey('token')) { + return response['token']!; + } else { + // Если нет токена, но есть message или errors + String errorMsg = ''; + if (response.containsKey('message')) { + errorMsg += '${response['message']!}\n'; + } + if (response.containsKey('errors')) { + final errors = response['errors']; + if (errors != null && errors is Map) { + (errors as Map).forEach((key, value) { + if (value is List && value.isNotEmpty) { + errorMsg += '${value.join('\n')}\n'; + } + }); + } + } + if (errorMsg.isNotEmpty) { + throw errorMsg.trim(); + } else { + throw 'Ошибка регистрации: $response'; + } + } + } on DioException catch (e) { + if (e.response != null && e.response?.statusCode == 422) { + final data = e.response?.data; + String errorMsg = ''; + if (data is Map) { + if (data.containsKey('message')) { + errorMsg += data['message'] + '\n'; + } + if (data.containsKey('errors')) { + final errors = data['errors']; + if (errors != null && errors is Map) { + (errors).forEach((key, value) { + if (value is List && value.isNotEmpty) { + errorMsg += '${value.join('\n')}\n'; + } + }); + } + } + } + if (errorMsg.isNotEmpty) { + throw errorMsg.trim(); + } else { + throw 'Ошибка регистрации: $data'; + } } - } catch (e) { rethrow; } } diff --git a/lib/features/settings/presentation/bloc/settings_cubit/settings_cubit.dart b/lib/features/settings/presentation/bloc/settings_cubit/settings_cubit.dart index 3cb047f6..ae498824 100644 --- a/lib/features/settings/presentation/bloc/settings_cubit/settings_cubit.dart +++ b/lib/features/settings/presentation/bloc/settings_cubit/settings_cubit.dart @@ -22,7 +22,11 @@ class SettingsCubit extends Cubit { final profile = await profileRepository.getMyProfile(); late final ConsultationRequestModel? consultantInfo; try { - consultantInfo = await consultantRepository.getMyRequestStatus(profile.slug); + if (profile.phoneConfirmationState.contains('confirmed')) { + consultantInfo = await consultantRepository.getMyRequestStatus(profile.slug); + } else { + consultantInfo = null; + } } catch (e) { consultantInfo = null; } diff --git a/test/features/profile/services/profile_service_test.dart b/test/features/profile/services/profile_service_test.dart index b2c51b01..106da096 100644 --- a/test/features/profile/services/profile_service_test.dart +++ b/test/features/profile/services/profile_service_test.dart @@ -19,6 +19,7 @@ void main() { id: 0, name: 'Alexander Avanesyan', email: 'mso7nueh@mail.ru', + phoneConfirmationState: '', isPublicProfile: true, isEntitySubscribedByMe: false, isBlockedByMe: false, From a134c2043b903a7d437546b438ccd7d171804a4f Mon Sep 17 00:00:00 2001 From: mso7nueh Date: Wed, 30 Jul 2025 14:33:28 +0300 Subject: [PATCH 2/8] upd ver pack --- android/app/build.gradle | 2 +- pubspec.yaml | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/android/app/build.gradle b/android/app/build.gradle index a5377cc6..274f5a87 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -29,7 +29,7 @@ android { defaultConfig { applicationId = "com.eatvioapp.app" - minSdk = flutter.minSdkVersion + minSdk = 23 targetSdk = flutter.targetSdkVersion versionCode = flutter.versionCode versionName = flutter.versionName diff --git a/pubspec.yaml b/pubspec.yaml index 4223ded7..17edab5a 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -61,8 +61,8 @@ dependencies: sentry_flutter: ^8.14.2 connectivity_plus: ^6.1.4 visibility_detector: ^0.4.0+2 - firebase_core: ^3.15.0 - firebase_messaging: ^15.2.8 + firebase_core: ^4.0.0 + firebase_messaging: ^16.0.0 http_parser: ^4.1.2 path: ^1.9.1 collection: ^1.19.1 @@ -77,7 +77,7 @@ dev_dependencies: build_runner: ^2.5.4 freezed: ^3.0.6 json_serializable: ^6.9.5 - retrofit_generator: ^9.2.0 + retrofit_generator: ^10.0.1 mockito: ^5.4.6 flutter_test: From 190e1781eee8c958fed460e738b2ebde91182b1d Mon Sep 17 00:00:00 2001 From: mso7nueh Date: Wed, 30 Jul 2025 15:41:43 +0300 Subject: [PATCH 3/8] fix: recipe create --- lib/core/const.dart | 1 - lib/features/create_recipe/reporitories/recipe_repository.dart | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/core/const.dart b/lib/core/const.dart index 31c47e9c..618a9866 100644 --- a/lib/core/const.dart +++ b/lib/core/const.dart @@ -1,5 +1,4 @@ String baseUrl = 'https://eatvio.ru'; -// String baseUrl = 'https://dev2.eatvio.com'; const List durationValues = [7, 14, 21]; diff --git a/lib/features/create_recipe/reporitories/recipe_repository.dart b/lib/features/create_recipe/reporitories/recipe_repository.dart index f0f860e9..289233a2 100644 --- a/lib/features/create_recipe/reporitories/recipe_repository.dart +++ b/lib/features/create_recipe/reporitories/recipe_repository.dart @@ -57,7 +57,7 @@ class RecipeRepository { 'type': recipe.type, 'state': 'active', 'title': recipe.title, - 'tags': recipe.tags, + 'tags[]': recipe.tags ?? [], 'description_md': recipe.description, 'video_url': recipe.videoUrl, 'ingredients': ingredientsMap, From 7192db31e45ecb0d1be350d2d7b7bd3410e8f8d1 Mon Sep 17 00:00:00 2001 From: mso7nueh Date: Thu, 31 Jul 2025 14:27:01 +0300 Subject: [PATCH 4/8] fix: upd ver --- pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pubspec.yaml b/pubspec.yaml index 17edab5a..10001259 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: eatvio_app description: A new Flutter project. -version: 1.2.4+54 +version: 1.2.6+60 publish_to: 'none' environment: From 8a26fa0990b9a405d1ae6ffcc18e58233595ae90 Mon Sep 17 00:00:00 2001 From: mso7nueh Date: Thu, 31 Jul 2025 14:55:35 +0300 Subject: [PATCH 5/8] fix: upd ver sdk --- .gitea/workflows/test.yml | 2 +- pubspec.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitea/workflows/test.yml b/.gitea/workflows/test.yml index 75372b09..fd291367 100644 --- a/.gitea/workflows/test.yml +++ b/.gitea/workflows/test.yml @@ -3,7 +3,7 @@ name: Eatvio App Android Test on: [ pull_request ] env: - flutter_version: "3.32.5" + flutter_version: "3.32.8" java_version: "21.x" flutter_channel: "stable" my_local_cache_dir: "/opt/hostedtoolcache/" diff --git a/pubspec.yaml b/pubspec.yaml index 10001259..bda9d6a9 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -4,7 +4,7 @@ version: 1.2.6+60 publish_to: 'none' environment: - sdk: '>=3.3.4 <4.0.0' + sdk: '>=3.8.0 <4.0.0' dependencies: flutter: From f5d27ed056035f2e6bc8abf5525e041fa70e02f2 Mon Sep 17 00:00:00 2001 From: mso7nueh Date: Fri, 1 Aug 2025 10:53:28 +0300 Subject: [PATCH 6/8] feat(plans): hide for ios --- lib/core/const.dart | 1 + .../feed/presentation/pages/feed_screen.dart | 182 +++--- .../feed/presentation/widgets/chip_group.dart | 9 +- .../presentation/pages/profile_screen.dart | 547 ++++-------------- 4 files changed, 184 insertions(+), 555 deletions(-) diff --git a/lib/core/const.dart b/lib/core/const.dart index 618a9866..f22f79aa 100644 --- a/lib/core/const.dart +++ b/lib/core/const.dart @@ -1,4 +1,5 @@ String baseUrl = 'https://eatvio.ru'; +bool hidePlans = true; const List durationValues = [7, 14, 21]; diff --git a/lib/features/feed/presentation/pages/feed_screen.dart b/lib/features/feed/presentation/pages/feed_screen.dart index b6869040..ce29b884 100644 --- a/lib/features/feed/presentation/pages/feed_screen.dart +++ b/lib/features/feed/presentation/pages/feed_screen.dart @@ -1,4 +1,5 @@ import 'package:easy_debounce/easy_debounce.dart'; +import 'package:eatvio_app/core/const.dart'; import 'package:eatvio_app/core/widgets/add_item_button.dart'; import 'package:eatvio_app/core/widgets/custom_search_bar.dart'; import 'package:eatvio_app/features/create_diet/presentation/create_diet_screen.dart'; @@ -32,24 +33,12 @@ class FeedScreen extends StatelessWidget { Widget build(BuildContext context) { return MultiBlocProvider( providers: [ - BlocProvider( - create: (context) => sl()..loadRecipesList(), - ), - BlocProvider( - create: (context) => sl()..getProfile(), - ), - BlocProvider( - create: (context) => sl()..loadFeedBlogPostList(), - ), - BlocProvider( - create: (context) => sl()..loadDiets(), - ), - BlocProvider( - create: (context) => sl()..loadPlans(), - ), - BlocProvider( - create: (context) => sl()..getConsultants(), - ), + BlocProvider(create: (context) => sl()..loadRecipesList()), + BlocProvider(create: (context) => sl()..getProfile()), + BlocProvider(create: (context) => sl()..loadFeedBlogPostList()), + BlocProvider(create: (context) => sl()..loadDiets()), + if (!hidePlans) BlocProvider(create: (context) => sl()..loadPlans()), + BlocProvider(create: (context) => sl()..getConsultants()), ], child: const FeedScreenContent(), ); @@ -69,7 +58,8 @@ class _FeedScreenContentState extends State { final dietsController = TextEditingController(); final plansController = TextEditingController(); final consultantsController = TextEditingController(); - final List chipsLabelList = ['Все', 'Рецепты', 'Диеты', 'Планы питания', 'Консультанты']; + + late final List chipsLabelList; int _selectedChipIndex = 0; final blogPostsScrollController = ScrollController(); final recipesScrollController = ScrollController(); @@ -78,12 +68,13 @@ class _FeedScreenContentState extends State { final consultantsScrollController = ScrollController(); @override - void initState() { + void initState() { + // Initialize chipsLabelList based on hidePlans setting + chipsLabelList = hidePlans ? ['Все', 'Рецепты', 'Диеты', 'Консультанты'] : ['Все', 'Рецепты', 'Диеты', 'Планы питания', 'Консультанты']; + consultantsScrollController.addListener(_onScrollConsultants); super.initState(); - } - - + } void _onScrollConsultants() { if (consultantsScrollController.offset >= consultantsScrollController.position.maxScrollExtent && !consultantsScrollController.position.outOfRange) {} @@ -108,45 +99,36 @@ class _FeedScreenContentState extends State { heroTag: 'recipesTagsFilter', backgroundColor: appTheme.blueA400, shape: const CircleBorder(), - child: const Icon( - Icons.filter_list_rounded, - color: Colors.white, - ), + child: const Icon(Icons.filter_list_rounded, color: Colors.white), onPressed: () async { final recipesCubit = context.read(); await showModalBottomSheet( useRootNavigator: true, context: context, - builder: (context) => TagsModalWidget( - recipesCubit: recipesCubit, - ), + builder: (context) => TagsModalWidget(recipesCubit: recipesCubit), ); recipesCubit.loadRecipesList(); }, ) : null, - appBar: AppBar( - backgroundColor: Colors.white, - toolbarHeight: 0, - ), + appBar: AppBar(backgroundColor: Colors.white, toolbarHeight: 0), backgroundColor: Colors.grey.shade200, body: NestedScrollView( controller: switch (_selectedChipIndex) { 0 => blogPostsScrollController, 1 => recipesScrollController, 2 => dietsScrollController, - 3 => plansScrollController, - 4 => consultantsScrollController, - _ => blogPostsScrollController + 3 when !hidePlans => plansScrollController, + 3 when hidePlans => consultantsScrollController, + 4 when !hidePlans => consultantsScrollController, + _ => blogPostsScrollController, }, headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) { return [ BlocBuilder( builder: (context, state) { return SliverAppBar( - shape: const RoundedRectangleBorder( - borderRadius: BorderRadius.vertical(bottom: Radius.circular(12)), - ), + shape: const RoundedRectangleBorder(borderRadius: BorderRadius.vertical(bottom: Radius.circular(12))), backgroundColor: Colors.white, foregroundColor: Colors.white, automaticallyImplyLeading: false, @@ -172,78 +154,71 @@ class _FeedScreenContentState extends State { searchController: switch (_selectedChipIndex) { 1 => recipesController, 2 => dietsController, - 3 => plansController, - 4 => consultantsController, + 3 when !hidePlans => plansController, + 3 when hidePlans => consultantsController, + 4 when !hidePlans => consultantsController, _ => postsController, }, onChanged: (query) { if (query.length > 2) { - EasyDebounce.debounce( - 'searchFeed', - const Duration(milliseconds: 500), - () { - switch (_selectedChipIndex) { - case 0: - context.read().loadFeedBlogPostList(query: query); - break; - case 1: - context.read().loadRecipesList(query: query); - break; - case 2: - context.read().loadDiets(query: query); - break; - case 3: - context.read().loadPlans(query: query); - break; - case 4: - context.read().getConsultants(); - break; - } - }, - ); + EasyDebounce.debounce('searchFeed', const Duration(milliseconds: 500), () { + switch (_selectedChipIndex) { + case 0: + context.read().loadFeedBlogPostList(query: query); + break; + case 1: + context.read().loadRecipesList(query: query); + break; + case 2: + context.read().loadDiets(query: query); + break; + case 3 when !hidePlans: + context.read().loadPlans(query: query); + break; + case 3 when hidePlans: + case 4 when !hidePlans: + context.read().getConsultants(); + break; + } + }); } else { - EasyDebounce.debounce( - 'searchFeed', - const Duration(milliseconds: 500), - () { - switch (_selectedChipIndex) { - case 0: - context.read().loadFeedBlogPostList(); - break; - case 1: - context.read().loadRecipesList(); - break; - case 2: - context.read().loadDiets(); - break; - case 3: - context.read().loadPlans(); - break; - case 4: - context.read().getConsultants(); - break; - } - }, - ); + EasyDebounce.debounce('searchFeed', const Duration(milliseconds: 500), () { + switch (_selectedChipIndex) { + case 0: + context.read().loadFeedBlogPostList(); + break; + case 1: + context.read().loadRecipesList(); + break; + case 2: + context.read().loadDiets(); + break; + case 3 when !hidePlans: + context.read().loadPlans(); + break; + case 3 when hidePlans: + case 4 when !hidePlans: + context.read().getConsultants(); + break; + } + }); } }, ), const SizedBox(width: 12), switch (_selectedChipIndex) { - 1 => AddItemButton( - onTap: () => GoRouter.of(context).pushNamed(RecipeCreateScreen.name), - ), + 1 => AddItemButton(onTap: () => GoRouter.of(context).pushNamed(RecipeCreateScreen.name)), 2 => AddItemButton( - onTap: state.profile?.roles.contains('consultant') ?? false - ? () async { - await GoRouter.of(context).pushNamed(CreateDietScreen.name); - } - : null, - ), - 3 => AddItemButton( - onTap: state.profile?.roles.contains('consultant') ?? false ? () => GoRouter.of(context).pushNamed(CreatePlanScreen.name) : null, - ), - _ => const AddItemButton() + onTap: state.profile?.roles.contains('consultant') ?? false + ? () async { + await GoRouter.of(context).pushNamed(CreateDietScreen.name); + } + : null, + ), + 3 when !hidePlans => AddItemButton( + onTap: state.profile?.roles.contains('consultant') ?? false ? () => GoRouter.of(context).pushNamed(CreatePlanScreen.name) : null, + ), + _ => const AddItemButton(), }, ], ), @@ -256,8 +231,9 @@ class _FeedScreenContentState extends State { 0 => const BlogPosts(), 1 => const Recipes(), 2 => const Diets(), - 3 => const Plans(), - 4 => const Consultants(), + 3 when !hidePlans => const Plans(), + 3 when hidePlans => const Consultants(), + 4 when !hidePlans => const Consultants(), _ => Center(child: Text(chipsLabelList[_selectedChipIndex])), }, ), diff --git a/lib/features/feed/presentation/widgets/chip_group.dart b/lib/features/feed/presentation/widgets/chip_group.dart index a8d88da1..183a5a76 100644 --- a/lib/features/feed/presentation/widgets/chip_group.dart +++ b/lib/features/feed/presentation/widgets/chip_group.dart @@ -2,12 +2,7 @@ import 'package:eatvio_app/features/feed/presentation/widgets/choice_chip_widget import 'package:flutter/widgets.dart'; class ChipGroup extends StatelessWidget { - const ChipGroup({ - super.key, - required this.selectedChipIndex, - required this.chipsLabelList, - required this.setSelectedChipIndex, - }); + const ChipGroup({super.key, required this.selectedChipIndex, required this.chipsLabelList, required this.setSelectedChipIndex}); final int selectedChipIndex; final List chipsLabelList; final void Function(int) setSelectedChipIndex; @@ -22,7 +17,7 @@ class ChipGroup extends StatelessWidget { child: Row( children: [ ...List.generate( - 5, + chipsLabelList.length, (index) => Padding( padding: const EdgeInsets.only(right: 8.0), child: ChoiceChipWidget( diff --git a/lib/features/profile/presentation/pages/profile_screen.dart b/lib/features/profile/presentation/pages/profile_screen.dart index 68213da5..211543a9 100644 --- a/lib/features/profile/presentation/pages/profile_screen.dart +++ b/lib/features/profile/presentation/pages/profile_screen.dart @@ -45,10 +45,7 @@ import 'package:url_launcher/url_launcher.dart'; class ProfileScreen extends StatefulWidget { final Author? author; - const ProfileScreen({ - super.key, - this.author, - }); + const ProfileScreen({super.key, this.author}); @override State createState() => _ProfileScreenState(); @@ -91,7 +88,7 @@ class _ProfileScreenState extends State { } if (isFirstFetch) { canSub = !state.profile.isEntitySubscribedByMe; - if (state.profile.roles.contains('consultant')) { + if (state.profile.roles.contains('consultant') && !hidePlans) { plansCubit.getPlans(state.profile.slug); } isFirstFetch = false; @@ -109,10 +106,7 @@ class _ProfileScreenState extends State { ), ); } else { - return Scaffold( - appBar: AppBar(), - body: const Loader(), - ); + return Scaffold(appBar: AppBar(), body: const Loader()); } }, ), @@ -130,9 +124,7 @@ class _ProfileScreenState extends State { Container( decoration: const BoxDecoration( color: Colors.white, - borderRadius: BorderRadius.vertical( - bottom: Radius.circular(16), - ), + borderRadius: BorderRadius.vertical(bottom: Radius.circular(16)), ), child: Column( crossAxisAlignment: CrossAxisAlignment.center, @@ -147,28 +139,15 @@ class _ProfileScreenState extends State { const SizedBox(width: 16), const Text( 'Консультант', - style: TextStyle( - fontSize: 16, - fontWeight: FontWeight.w600, - color: Color( - 0xFF323F4B, - ), - ), + style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600, color: Color(0xFF323F4B)), ), const SizedBox(width: 12), Container( padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8), - decoration: BoxDecoration( - color: const Color(0xFFF6FAFF), - borderRadius: BorderRadius.circular(12), - ), + decoration: BoxDecoration(color: const Color(0xFFF6FAFF), borderRadius: BorderRadius.circular(12)), child: Text( '${state.consultantInfo!.ratingPlace}-й в рейтинге', - style: TextStyle( - fontSize: 16, - fontWeight: FontWeight.w600, - color: appTheme.blueA400, - ), + style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600, color: appTheme.blueA400), ), ), ], @@ -177,17 +156,10 @@ class _ProfileScreenState extends State { const Row( children: [ SizedBox(width: 16), - Icon( - Icons.done_rounded, - color: Colors.green, - ), + Icon(Icons.done_rounded, color: Colors.green), Text( 'Медицинское образование', - style: TextStyle( - color: Color(0xFF323F4B), - fontSize: 14, - fontWeight: FontWeight.w600, - ), + style: TextStyle(color: Color(0xFF323F4B), fontSize: 14, fontWeight: FontWeight.w600), ), ], ), @@ -205,7 +177,7 @@ class _ProfileScreenState extends State { if (state.profile.roles.contains('consultant') && state.consultantInfo != null) _socialLinks(state), if (state.profile.roles.contains('consultant') && state.consultantInfo != null) _education(state), if (state.profile.roles.contains('consultant') && state.consultantInfo != null) _diplomasAndCertificates(state), - if (state.profile.roles.contains('consultant') && state.consultantInfo != null) _activePlans(state), + if (state.profile.roles.contains('consultant') && state.consultantInfo != null && !hidePlans) _activePlans(state), _blogPosts(state), ], ), @@ -216,9 +188,7 @@ class _ProfileScreenState extends State { Scaffold _myProfileScreen(ProfileStateLoaded state) { return Scaffold( backgroundColor: Colors.grey.shade200, - appBar: AppBar( - toolbarHeight: widget.author == null ? 0 : null, - ), + appBar: AppBar(toolbarHeight: widget.author == null ? 0 : null), body: SingleChildScrollView( child: Column( crossAxisAlignment: CrossAxisAlignment.start, @@ -226,9 +196,7 @@ class _ProfileScreenState extends State { Container( decoration: const BoxDecoration( color: Colors.white, - borderRadius: BorderRadius.vertical( - bottom: Radius.circular(16), - ), + borderRadius: BorderRadius.vertical(bottom: Radius.circular(16)), ), child: Column( crossAxisAlignment: CrossAxisAlignment.center, @@ -243,28 +211,15 @@ class _ProfileScreenState extends State { const SizedBox(width: 16), const Text( 'Консультант', - style: TextStyle( - fontSize: 16, - fontWeight: FontWeight.w600, - color: Color( - 0xFF323F4B, - ), - ), + style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600, color: Color(0xFF323F4B)), ), const SizedBox(width: 12), Container( padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8), - decoration: BoxDecoration( - color: const Color(0xFFF6FAFF), - borderRadius: BorderRadius.circular(12), - ), + decoration: BoxDecoration(color: const Color(0xFFF6FAFF), borderRadius: BorderRadius.circular(12)), child: Text( '${state.consultantInfo!.ratingPlace}-й в рейтинге', - style: TextStyle( - fontSize: 16, - fontWeight: FontWeight.w600, - color: appTheme.blueA400, - ), + style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600, color: appTheme.blueA400), ), ), ], @@ -273,17 +228,10 @@ class _ProfileScreenState extends State { const Row( children: [ SizedBox(width: 16), - Icon( - Icons.done_rounded, - color: Colors.green, - ), + Icon(Icons.done_rounded, color: Colors.green), Text( 'Медицинское образование', - style: TextStyle( - color: Color(0xFF323F4B), - fontSize: 14, - fontWeight: FontWeight.w600, - ), + style: TextStyle(color: Color(0xFF323F4B), fontSize: 14, fontWeight: FontWeight.w600), ), ], ), @@ -299,7 +247,7 @@ class _ProfileScreenState extends State { if (state.profile.roles.contains('consultant')) _education(state), if (state.profile.roles.contains('consultant')) _diplomasAndCertificates(state), Padding(padding: const EdgeInsets.only(bottom: 16), child: _charts()), - if (state.profile.roles.contains('consultant')) _activePlans(state), + if (state.profile.roles.contains('consultant') && !hidePlans) _activePlans(state), _newBlogPostButton(), _blogPosts(state), ], @@ -309,7 +257,7 @@ class _ProfileScreenState extends State { } Widget _activePlans(ProfileStateLoaded state) { - if (!state.profile.roles.contains('consultant')) { + if (!state.profile.roles.contains('consultant') || hidePlans) { return const SizedBox.shrink(); } return BlocBuilder( @@ -328,12 +276,7 @@ class _ProfileScreenState extends State { children: [ Text( 'Активные планы', - style: TextStyle( - color: Color(0xFF323F4B), - fontSize: 24, - height: 1, - fontWeight: FontWeight.w600, - ), + style: TextStyle(color: Color(0xFF323F4B), fontSize: 24, height: 1, fontWeight: FontWeight.w600), ), ], ), @@ -343,10 +286,7 @@ class _ProfileScreenState extends State { height: 781, child: PageView.builder( itemBuilder: (BuildContext context, int index) { - return PlanWidget( - plan: state.plansList[index], - index: index, - ); + return PlanWidget(plan: state.plansList[index], index: index); }, onPageChanged: (bullet) { setState(() { @@ -370,17 +310,11 @@ class _ProfileScreenState extends State { Container _bullets(int currentBullet, int bulletCount) { return Container( padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8), - decoration: BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.circular(20), - ), + decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.circular(20)), child: Row( mainAxisSize: MainAxisSize.min, children: [ - for (int i = 0; i < bulletCount; i++) ...[ - _bullet(i == currentBullet), - i < bulletCount - 1 ? const SizedBox(width: 4) : const SizedBox.shrink(), - ], + for (int i = 0; i < bulletCount; i++) ...[_bullet(i == currentBullet), i < bulletCount - 1 ? const SizedBox(width: 4) : const SizedBox.shrink()], ], ), ); @@ -391,10 +325,7 @@ class _ProfileScreenState extends State { width: isActive ? 10 : 8, height: isActive ? 10 : 8, duration: const Duration(milliseconds: 150), - decoration: BoxDecoration( - color: isActive ? appTheme.blueA400 : const Color(0xFFD7D9DC), - shape: BoxShape.circle, - ), + decoration: BoxDecoration(color: isActive ? appTheme.blueA400 : const Color(0xFFD7D9DC), shape: BoxShape.circle), ); } @@ -411,25 +342,15 @@ class _ProfileScreenState extends State { borderRadius: BorderRadius.circular(8), child: Ink( padding: const EdgeInsets.all(12), - decoration: BoxDecoration( - color: const Color(0xFFF6FAFF), - borderRadius: BorderRadius.circular(8), - ), + decoration: BoxDecoration(color: const Color(0xFFF6FAFF), borderRadius: BorderRadius.circular(8)), child: const Row( mainAxisAlignment: MainAxisAlignment.center, children: [ - Icon( - Icons.add_circle_outline_rounded, - color: Color(0xFF2F80ED), - ), + Icon(Icons.add_circle_outline_rounded, color: Color(0xFF2F80ED)), SizedBox(width: 12), Text( 'Новая запись', - style: TextStyle( - fontSize: 18, - fontWeight: FontWeight.w600, - color: Color(0xFF2F80ED), - ), + style: TextStyle(fontSize: 18, fontWeight: FontWeight.w600, color: Color(0xFF2F80ED)), ), ], ), @@ -454,12 +375,7 @@ class _ProfileScreenState extends State { children: [ const Text( 'Дипломы\nи сертификаты', - style: TextStyle( - color: Color(0xFF323F4B), - fontSize: 24, - height: 1, - fontWeight: FontWeight.w600, - ), + style: TextStyle(color: Color(0xFF323F4B), fontSize: 24, height: 1, fontWeight: FontWeight.w600), ), GestureDetector( onTap: () { @@ -467,11 +383,7 @@ class _ProfileScreenState extends State { }, child: Text( widget.author == null || widget.author!.authorIsMe ? 'Редактировать' : '', - style: const TextStyle( - color: Color(0xFF2F80ED), - fontSize: 16, - fontWeight: FontWeight.w500, - ), + style: const TextStyle(color: Color(0xFF2F80ED), fontSize: 16, fontWeight: FontWeight.w500), ), ), ], @@ -491,17 +403,14 @@ class _ProfileScreenState extends State { child: Row( children: [ if (state.consultantInfo!.photos.isNotEmpty) - ...List.generate( - state.consultantInfo!.photos.length * 2 - 1, - (index) { - if (index.isEven) { - final photo = state.consultantInfo!.photos[index ~/ 2]; - return _diplomaImage(photo.url); - } else { - return const SizedBox(width: 8); - } - }, - ), + ...List.generate(state.consultantInfo!.photos.length * 2 - 1, (index) { + if (index.isEven) { + final photo = state.consultantInfo!.photos[index ~/ 2]; + return _diplomaImage(photo.url); + } else { + return const SizedBox(width: 8); + } + }), ], ), ), @@ -515,24 +424,13 @@ class _ProfileScreenState extends State { GestureDetector _diplomaImage(String url) { return GestureDetector( onTap: () { - context.pushTransparentRoute( - rootNavigator: true, - PhotoViewScreen( - imageUrls: [url], - index: 0, - ), - ); + context.pushTransparentRoute(rootNavigator: true, PhotoViewScreen(imageUrls: [url], index: 0)); }, child: Hero( tag: url, child: ClipRRect( borderRadius: BorderRadius.circular(8), - child: CachedNetworkImage( - imageUrl: url, - fit: BoxFit.fitHeight, - width: MediaQuery.of(context).size.width / 3 - (60 / 3), - height: 160, - ), + child: CachedNetworkImage(imageUrl: url, fit: BoxFit.fitHeight, width: MediaQuery.of(context).size.width / 3 - (60 / 3), height: 160), ), ), ); @@ -555,11 +453,7 @@ class _ProfileScreenState extends State { children: [ const Text( 'Образование', - style: TextStyle( - color: Color(0xFF323F4B), - fontSize: 24, - fontWeight: FontWeight.w600, - ), + style: TextStyle(color: Color(0xFF323F4B), fontSize: 24, fontWeight: FontWeight.w600), ), GestureDetector( onTap: () { @@ -567,11 +461,7 @@ class _ProfileScreenState extends State { }, child: Text( widget.author == null || widget.author!.authorIsMe ? 'Редактировать' : '', - style: const TextStyle( - color: Color(0xFF2F80ED), - fontSize: 16, - fontWeight: FontWeight.w500, - ), + style: const TextStyle(color: Color(0xFF2F80ED), fontSize: 16, fontWeight: FontWeight.w500), ), ), ], @@ -590,8 +480,10 @@ class _ProfileScreenState extends State { ListView.separated( shrinkWrap: true, physics: const NeverScrollableScrollPhysics(), - itemBuilder: (context, index) => _educationBlock(state.consultantInfo!.educationModel.completedCourses![index].values.first.title, - state.consultantInfo!.educationModel.completedCourses![index].values.first.date), + itemBuilder: (context, index) => _educationBlock( + state.consultantInfo!.educationModel.completedCourses![index].values.first.title, + state.consultantInfo!.educationModel.completedCourses![index].values.first.date, + ), separatorBuilder: (context, index) => const SizedBox(height: 8), itemCount: state.consultantInfo!.educationModel.completedCourses!.length, ), @@ -621,22 +513,12 @@ class _ProfileScreenState extends State { children: [ Text( title, - style: const TextStyle( - height: 1, - color: Color(0xFF323F4B), - fontWeight: FontWeight.w500, - fontSize: 16, - ), + style: const TextStyle(height: 1, color: Color(0xFF323F4B), fontWeight: FontWeight.w500, fontSize: 16), ), const SizedBox(height: 4), Text( formattedDate, - style: const TextStyle( - height: 1, - color: Color(0xFF6D6F71), - fontWeight: FontWeight.w500, - fontSize: 14, - ), + style: const TextStyle(height: 1, color: Color(0xFF6D6F71), fontWeight: FontWeight.w500, fontSize: 14), ), ], ), @@ -660,12 +542,7 @@ class _ProfileScreenState extends State { children: [ _socialLinkButton( () { - launchUrl( - Uri.parse( - state.consultantInfo!.educationModel.vkLink ?? '', - ), - mode: LaunchMode.externalApplication, - ); + launchUrl(Uri.parse(state.consultantInfo!.educationModel.vkLink ?? ''), mode: LaunchMode.externalApplication); }, 'assets/icons/vk.svg', state.consultantInfo!.educationModel.vkLink!.isEmpty ? true : false, @@ -673,12 +550,7 @@ class _ProfileScreenState extends State { const SizedBox(width: 12), _socialLinkButton( () { - launchUrl( - Uri.parse( - state.consultantInfo!.educationModel.tgLink ?? '', - ), - mode: LaunchMode.externalApplication, - ); + launchUrl(Uri.parse(state.consultantInfo!.educationModel.tgLink ?? ''), mode: LaunchMode.externalApplication); }, 'assets/icons/telegram.svg', state.consultantInfo!.educationModel.tgLink!.isEmpty ? true : false, @@ -686,12 +558,7 @@ class _ProfileScreenState extends State { const SizedBox(width: 12), _socialLinkButton( () { - launchUrl( - Uri.parse( - state.consultantInfo!.educationModel.personalSiteLink ?? '', - ), - mode: LaunchMode.externalApplication, - ); + launchUrl(Uri.parse(state.consultantInfo!.educationModel.personalSiteLink ?? ''), mode: LaunchMode.externalApplication); }, 'assets/icons/web.svg', state.consultantInfo!.educationModel.personalSiteLink!.isEmpty ? true : false, @@ -709,10 +576,7 @@ class _ProfileScreenState extends State { borderRadius: BorderRadius.circular(20), child: Ink( width: MediaQuery.of(context).size.width / 3 - (56 / 3), - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(20), - color: const Color(0xFFF6F6F6), - ), + decoration: BoxDecoration(borderRadius: BorderRadius.circular(20), color: const Color(0xFFF6F6F6)), child: Padding( padding: const EdgeInsets.symmetric(horizontal: 40, vertical: 16), child: SvgPicture.asset( @@ -734,20 +598,13 @@ class _ProfileScreenState extends State { child: Ink( padding: const EdgeInsets.all(8), width: MediaQuery.of(context).size.width, - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(12), - color: Colors.white, - ), + decoration: BoxDecoration(borderRadius: BorderRadius.circular(12), color: Colors.white), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ const Text( 'Достижения', - style: TextStyle( - color: Color(0xFF6D6F71), - fontSize: 14, - fontWeight: FontWeight.w600, - ), + style: TextStyle(color: Color(0xFF6D6F71), fontSize: 14, fontWeight: FontWeight.w600), ), const SizedBox(height: 8), SingleChildScrollView( @@ -759,51 +616,25 @@ class _ProfileScreenState extends State { ? Tooltip( message: state.profile.badges[i].description, triggerMode: TooltipTriggerMode.tap, - textStyle: const TextStyle( - color: Colors.black, - fontSize: 16, - fontWeight: FontWeight.w500, - ), + textStyle: const TextStyle(color: Colors.black, fontSize: 16, fontWeight: FontWeight.w500), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(4), - boxShadow: [ - BoxShadow( - color: Colors.black.withAlpha((255 * 0.2).toInt()), - blurRadius: 32, - ) - ], - ), - child: SvgPicture.network( - '$baseUrl/storage/${state.profile.badges[i].image}', - width: 40, - height: 40, + boxShadow: [BoxShadow(color: Colors.black.withAlpha((255 * 0.2).toInt()), blurRadius: 32)], ), + child: SvgPicture.network('$baseUrl/storage/${state.profile.badges[i].image}', width: 40, height: 40), ) : Tooltip( message: state.profile.badges[i].description, margin: const EdgeInsets.symmetric(horizontal: 32), triggerMode: TooltipTriggerMode.tap, - textStyle: const TextStyle( - color: Colors.black, - fontSize: 16, - fontWeight: FontWeight.w500, - ), + textStyle: const TextStyle(color: Colors.black, fontSize: 16, fontWeight: FontWeight.w500), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(4), - boxShadow: [ - BoxShadow( - color: Colors.black.withAlpha((255 * 0.2).toInt()), - blurRadius: 32, - ) - ], - ), - child: CachedNetworkImage( - imageUrl: '$baseUrl/storage/${state.profile.badges[i].image}', - width: 40, - height: 40, + boxShadow: [BoxShadow(color: Colors.black.withAlpha((255 * 0.2).toInt()), blurRadius: 32)], ), + child: CachedNetworkImage(imageUrl: '$baseUrl/storage/${state.profile.badges[i].image}', width: 40, height: 40), ), i < state.profile.badges.length - 1 ? const SizedBox(width: 8) : const SizedBox.shrink(), ], @@ -823,21 +654,12 @@ class _ProfileScreenState extends State { child: Row( children: [ InkWell( - onTap: () => GoRouter.of(context).pushNamed( - 'subsScreen', - extra: SubType.subscriptions, - pathParameters: { - 'slug': state.profile.slug, - }, - ), + onTap: () => GoRouter.of(context).pushNamed('subsScreen', extra: SubType.subscriptions, pathParameters: {'slug': state.profile.slug}), borderRadius: BorderRadius.circular(12), child: Ink( padding: const EdgeInsets.all(8), width: MediaQuery.of(context).size.width / 2 - 6, - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(12), - color: Colors.white, - ), + decoration: BoxDecoration(borderRadius: BorderRadius.circular(12), color: Colors.white), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, crossAxisAlignment: CrossAxisAlignment.end, @@ -847,47 +669,27 @@ class _ProfileScreenState extends State { children: [ const Text( 'Подписки', - style: TextStyle( - color: Color(0xFF6D6F71), - fontSize: 14, - fontWeight: FontWeight.w600, - ), + style: TextStyle(color: Color(0xFF6D6F71), fontSize: 14, fontWeight: FontWeight.w600), ), Text( '${state.profile.subscriptions.length}', - style: const TextStyle( - color: Color(0xFF323F4B), - fontSize: 22, - fontWeight: FontWeight.w700, - ), + style: const TextStyle(color: Color(0xFF323F4B), fontSize: 22, fontWeight: FontWeight.w700), ), ], ), - Padding( - padding: const EdgeInsets.only(right: 8), - child: _miniAvatars(state.profile.subscriptions), - ), + Padding(padding: const EdgeInsets.only(right: 8), child: _miniAvatars(state.profile.subscriptions)), ], ), ), ), const SizedBox(width: 4), InkWell( - onTap: () => GoRouter.of(context).pushNamed( - 'subsScreen', - extra: SubType.subscribers, - pathParameters: { - 'slug': state.profile.slug, - }, - ), + onTap: () => GoRouter.of(context).pushNamed('subsScreen', extra: SubType.subscribers, pathParameters: {'slug': state.profile.slug}), borderRadius: BorderRadius.circular(12), child: Ink( padding: const EdgeInsets.all(8), width: MediaQuery.of(context).size.width / 2 - 6, - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(12), - color: Colors.white, - ), + decoration: BoxDecoration(borderRadius: BorderRadius.circular(12), color: Colors.white), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, crossAxisAlignment: CrossAxisAlignment.end, @@ -897,26 +699,15 @@ class _ProfileScreenState extends State { children: [ const Text( 'Подписчики', - style: TextStyle( - color: Color(0xFF6D6F71), - fontSize: 14, - fontWeight: FontWeight.w600, - ), + style: TextStyle(color: Color(0xFF6D6F71), fontSize: 14, fontWeight: FontWeight.w600), ), Text( '${state.profile.subscribers.length}', - style: const TextStyle( - color: Color(0xFF323F4B), - fontSize: 22, - fontWeight: FontWeight.w700, - ), + style: const TextStyle(color: Color(0xFF323F4B), fontSize: 22, fontWeight: FontWeight.w700), ), ], ), - Padding( - padding: const EdgeInsets.only(right: 8), - child: _miniAvatars(state.profile.subscribers), - ), + Padding(padding: const EdgeInsets.only(right: 8), child: _miniAvatars(state.profile.subscribers)), ], ), ), @@ -934,13 +725,7 @@ class _ProfileScreenState extends State { for (int i = 0; i < maxLength; i++) Align( widthFactor: 0.8, - child: CircleAvatar( - radius: 14, - foregroundImage: NetworkImage( - urls[i], - ), - backgroundImage: const AssetImage('assets/images/no_avatar.png'), - ), + child: CircleAvatar(radius: 14, foregroundImage: NetworkImage(urls[i]), backgroundImage: const AssetImage('assets/images/no_avatar.png')), ), ], ); @@ -951,10 +736,7 @@ class _ProfileScreenState extends State { padding: const EdgeInsets.symmetric(vertical: 16), shrinkWrap: true, physics: const NeverScrollableScrollPhysics(), - itemBuilder: (context, index) => ProfileBlogPostWidget( - index: index, - profileCubit: profileCubit, - ), + itemBuilder: (context, index) => ProfileBlogPostWidget(index: index, profileCubit: profileCubit), separatorBuilder: (context, index) => const SizedBox(height: 8), itemCount: state.blogPosts.length, ); @@ -968,13 +750,7 @@ class _ProfileScreenState extends State { return Container( alignment: Alignment.centerLeft, padding: const EdgeInsets.all(16), - child: Text( - text, - style: TextStyle( - color: Colors.black.withValues(alpha: 0.4), - height: 1, - ), - ), + child: Text(text, style: TextStyle(color: Colors.black.withValues(alpha: 0.4), height: 1)), ); } @@ -986,13 +762,7 @@ class _ProfileScreenState extends State { PopupMenuButton( onSelected: (value) async { if (value == 'view') { - context.pushTransparentRoute( - rootNavigator: true, - PhotoViewScreen( - imageUrls: [baseUrl + state.profile.profilePhotoUrl], - index: 0, - ), - ); + context.pushTransparentRoute(rootNavigator: true, PhotoViewScreen(imageUrls: [baseUrl + state.profile.profilePhotoUrl], index: 0)); } if (value == 'replace') { showCupertinoModalPopup( @@ -1019,13 +789,7 @@ class _ProfileScreenState extends State { context: context, ); }, - child: const Row( - children: [ - Icon(Icons.photo_camera), - SizedBox(width: 8), - Text('Фото'), - ], - ), + child: const Row(children: [Icon(Icons.photo_camera), SizedBox(width: 8), Text('Фото')]), ), CupertinoActionSheetAction( onPressed: () async { @@ -1045,13 +809,7 @@ class _ProfileScreenState extends State { context: context, ); }, - child: const Row( - children: [ - Icon(Icons.photo), - SizedBox(width: 8), - Text('Галерея'), - ], - ), + child: const Row(children: [Icon(Icons.photo), SizedBox(width: 8), Text('Галерея')]), ), ], cancelButton: CupertinoActionSheetAction( @@ -1069,20 +827,9 @@ class _ProfileScreenState extends State { } }, itemBuilder: (context) => [ - const PopupMenuItem( - value: 'view', - child: Text('Посмотреть'), - ), - if (widget.author == null || widget.author!.authorIsMe) - const PopupMenuItem( - value: 'replace', - child: Text('Заменить'), - ), - if (widget.author == null || widget.author!.authorIsMe) - const PopupMenuItem( - value: 'delete', - child: Text('Удалить'), - ), + const PopupMenuItem(value: 'view', child: Text('Посмотреть')), + if (widget.author == null || widget.author!.authorIsMe) const PopupMenuItem(value: 'replace', child: Text('Заменить')), + if (widget.author == null || widget.author!.authorIsMe) const PopupMenuItem(value: 'delete', child: Text('Удалить')), ], child: Hero( tag: state.profile.profilePhotoUrl, @@ -1101,12 +848,7 @@ class _ProfileScreenState extends State { children: [ Text( '${state.profileDetails.firstName} ${state.profileDetails.lastName}', - style: const TextStyle( - color: Colors.black, - fontWeight: FontWeight.w600, - fontSize: 16, - height: 1, - ), + style: const TextStyle(color: Colors.black, fontWeight: FontWeight.w600, fontSize: 16, height: 1), ), const SizedBox(height: 8), GestureDetector( @@ -1124,11 +866,7 @@ class _ProfileScreenState extends State { children: [ const Text( 'Подробнее', - style: TextStyle( - fontSize: 20, - fontWeight: FontWeight.w700, - color: Color(0xFF323F4B), - ), + style: TextStyle(fontSize: 20, fontWeight: FontWeight.w700, color: Color(0xFF323F4B)), ), const SizedBox(height: 16), _additional('Дата рожденя: ', state.profileDetails.birthdate), @@ -1148,19 +886,11 @@ class _ProfileScreenState extends State { }, child: const Row( children: [ - Icon( - Icons.info_outline, - size: 20, - color: Color(0xFF6D6F71), - ), + Icon(Icons.info_outline, size: 20, color: Color(0xFF6D6F71)), SizedBox(width: 4), Text( 'Дополнительно', - style: TextStyle( - color: Color(0xFF6D6F71), - fontSize: 14, - fontWeight: FontWeight.w500, - ), + style: TextStyle(color: Color(0xFF6D6F71), fontSize: 14, fontWeight: FontWeight.w500), ), ], ), @@ -1173,10 +903,7 @@ class _ProfileScreenState extends State { if (value == 'share') { final box = context.findRenderObject() as RenderBox?; SharePlus.instance.share( - ShareParams( - uri: Uri.parse('$baseUrl/ru/profile/${state.profile.slug}'), - sharePositionOrigin: box!.localToGlobal(Offset.zero) & box.size, - ), + ShareParams(uri: Uri.parse('$baseUrl/ru/profile/${state.profile.slug}'), sharePositionOrigin: box!.localToGlobal(Offset.zero) & box.size), ); } else if (value == 'block') { isFirstFetch = true; @@ -1198,33 +925,15 @@ class _ProfileScreenState extends State { showModalBottomSheet( context: context, isScrollControlled: true, - builder: (context) => ComplainingBottomSheet( - complainedContentType: ComplainedContent.profile, - slug: widget.author?.authorSlug, - ), + builder: (context) => ComplainingBottomSheet(complainedContentType: ComplainedContent.profile, slug: widget.author?.authorSlug), ); } }, itemBuilder: (context) => [ - const PopupMenuItem( - value: 'share', - child: Text('Поделиться'), - ), - if (widget.author != null) - const PopupMenuItem( - value: 'complain', - child: Text('Пожаловаться'), - ), - if (widget.author != null && !state.profile.isBlockedByMe) - const PopupMenuItem( - value: 'block', - child: Text('Заблокировать'), - ), - if (widget.author != null && state.profile.isBlockedByMe) - const PopupMenuItem( - value: 'unblock', - child: Text('Разблокировать'), - ), + const PopupMenuItem(value: 'share', child: Text('Поделиться')), + if (widget.author != null) const PopupMenuItem(value: 'complain', child: Text('Пожаловаться')), + if (widget.author != null && !state.profile.isBlockedByMe) const PopupMenuItem(value: 'block', child: Text('Заблокировать')), + if (widget.author != null && state.profile.isBlockedByMe) const PopupMenuItem(value: 'unblock', child: Text('Разблокировать')), ], child: const Icon(Icons.more_horiz_rounded), ), @@ -1238,19 +947,11 @@ class _ProfileScreenState extends State { children: [ Text( title, - style: const TextStyle( - fontSize: 16, - fontWeight: FontWeight.w500, - color: Color(0xFF6D6F71), - ), + style: const TextStyle(fontSize: 16, fontWeight: FontWeight.w500, color: Color(0xFF6D6F71)), ), Text( value, - style: const TextStyle( - fontSize: 16, - fontWeight: FontWeight.w500, - color: Color(0xFF323F4B), - ), + style: const TextStyle(fontSize: 16, fontWeight: FontWeight.w500, color: Color(0xFF323F4B)), ), ], ); @@ -1266,16 +967,8 @@ class _ProfileScreenState extends State { alignment: Alignment.center, padding: const EdgeInsets.all(8), width: (MediaQuery.of(context).size.width - 40) / 2, - decoration: BoxDecoration( - color: appTheme.blueA400.withValues(alpha: 0.1), - borderRadius: BorderRadius.circular(16), - ), - child: Text( - 'Сообщение', - style: TextStyle( - color: appTheme.blueA400, - ), - ), + decoration: BoxDecoration(color: appTheme.blueA400.withValues(alpha: 0.1), borderRadius: BorderRadius.circular(16)), + child: Text('Сообщение', style: TextStyle(color: appTheme.blueA400)), ), ), const SizedBox(width: 8), @@ -1290,16 +983,8 @@ class _ProfileScreenState extends State { alignment: Alignment.center, padding: const EdgeInsets.all(8), width: (MediaQuery.of(context).size.width - 40) / 2, - decoration: BoxDecoration( - color: !canSub ? Colors.grey.shade200 : appTheme.blueA400, - borderRadius: BorderRadius.circular(16), - ), - child: Text( - !canSub ? 'Отписаться' : 'Подписаться', - style: TextStyle( - color: !canSub ? Colors.black : Colors.white, - ), - ), + decoration: BoxDecoration(color: !canSub ? Colors.grey.shade200 : appTheme.blueA400, borderRadius: BorderRadius.circular(16)), + child: Text(!canSub ? 'Отписаться' : 'Подписаться', style: TextStyle(color: !canSub ? Colors.black : Colors.white)), ), ), const SizedBox(width: 16), @@ -1318,33 +1003,17 @@ class _ProfileScreenState extends State { SingleChildScrollView( padding: const EdgeInsets.symmetric(horizontal: 16), scrollDirection: Axis.horizontal, - child: Row( - children: [ - _choiceChipWidget(0), - const SizedBox(width: 8), - _choiceChipWidget(1), - const SizedBox(width: 8), - _choiceChipWidget(2), - ], - ), + child: Row(children: [_choiceChipWidget(0), const SizedBox(width: 8), _choiceChipWidget(1), const SizedBox(width: 8), _choiceChipWidget(2)]), ), Builder( builder: (context) { switch (_selectedChipIndex) { case 0: - return WeightChartWidget( - weightPoints: weightPoints, - profileCubit: profileCubit, - ); + return WeightChartWidget(weightPoints: weightPoints, profileCubit: profileCubit); case 1: - return CircumferenceChartWidget( - circumferencePoints: circumferencePoints, - profileCubit: profileCubit, - ); + return CircumferenceChartWidget(circumferencePoints: circumferencePoints, profileCubit: profileCubit); case 2: - return ImtChartWidget( - weightPoints: weightPoints, - ); + return ImtChartWidget(weightPoints: weightPoints); default: return const SizedBox.shrink(); } @@ -1377,16 +1046,10 @@ class _ProfileScreenState extends State { pressElevation: 0, showCheckmark: false, side: BorderSide.none, - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(16), - ), + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(16)), padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4), label: Text(chipsIntervalLabelList[index]), - labelStyle: TextStyle( - color: appTheme.gray600, - fontWeight: FontWeight.w500, - fontSize: 12, - ), + labelStyle: TextStyle(color: appTheme.gray600, fontWeight: FontWeight.w500, fontSize: 12), selected: _selectedIntervalChipIndex == index, onSelected: (bool selected) { profileCubit.getMyProfile(period: chipsIntervalList[index]); @@ -1403,16 +1066,10 @@ class _ProfileScreenState extends State { pressElevation: 0, showCheckmark: false, side: BorderSide.none, - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(16), - ), + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(16)), padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4), label: Text(chipsLabelList[index]), - labelStyle: TextStyle( - color: index == _selectedChipIndex ? Colors.white : appTheme.gray600, - fontWeight: FontWeight.w500, - fontSize: 12, - ), + labelStyle: TextStyle(color: index == _selectedChipIndex ? Colors.white : appTheme.gray600, fontWeight: FontWeight.w500, fontSize: 12), selected: _selectedChipIndex == index, backgroundColor: appTheme.gray100, onSelected: (bool selected) { From 49b597d5ae6edd21c9363389f5f08d1026684405 Mon Sep 17 00:00:00 2001 From: mso7nueh Date: Fri, 1 Aug 2025 11:30:58 +0300 Subject: [PATCH 7/8] fix: update versions --- android/app/build.gradle | 6 ++--- android/gradle.properties | 2 +- .../gradle/wrapper/gradle-wrapper.properties | 2 +- android/settings.gradle | 2 +- pubspec.yaml | 26 +++++++++---------- 5 files changed, 19 insertions(+), 19 deletions(-) diff --git a/android/app/build.gradle b/android/app/build.gradle index 274f5a87..c9fe6d27 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -19,12 +19,12 @@ android { ndkVersion = "27.0.12077973" compileOptions { - sourceCompatibility = JavaVersion.VERSION_21 - targetCompatibility = JavaVersion.VERSION_21 + sourceCompatibility = JavaVersion.VERSION_11 + targetCompatibility = JavaVersion.VERSION_11 } kotlinOptions { - jvmTarget = 21 + jvmTarget = JavaVersion.VERSION_11.toString() } defaultConfig { diff --git a/android/gradle.properties b/android/gradle.properties index 25971708..f018a618 100644 --- a/android/gradle.properties +++ b/android/gradle.properties @@ -1,3 +1,3 @@ -org.gradle.jvmargs=-Xmx4G -XX:MaxMetaspaceSize=2G -XX:+HeapDumpOnOutOfMemoryError +org.gradle.jvmargs=-Xmx8G -XX:MaxMetaspaceSize=4G -XX:ReservedCodeCacheSize=512m -XX:+HeapDumpOnOutOfMemoryError android.useAndroidX=true android.enableJetifier=true diff --git a/android/gradle/wrapper/gradle-wrapper.properties b/android/gradle/wrapper/gradle-wrapper.properties index f587a472..ac3b4792 100644 --- a/android/gradle/wrapper/gradle-wrapper.properties +++ b/android/gradle/wrapper/gradle-wrapper.properties @@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.1-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.12-all.zip diff --git a/android/settings.gradle b/android/settings.gradle index 833c476b..29eab0d3 100644 --- a/android/settings.gradle +++ b/android/settings.gradle @@ -22,7 +22,7 @@ plugins { // START: FlutterFire Configuration id "com.google.gms.google-services" version "4.4.2" apply false // END: FlutterFire Configuration - id "org.jetbrains.kotlin.android" version "2.0.21" apply false + id "org.jetbrains.kotlin.android" version "2.1.0" apply false } include ":app" diff --git a/pubspec.yaml b/pubspec.yaml index bda9d6a9..fe27d891 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -18,28 +18,28 @@ dependencies: cached_network_image: ^3.4.1 flutter_svg: ^2.2.0 equatable: ^2.0.7 - freezed_annotation: ^3.0.0 + freezed_annotation: ^3.1.0 json_annotation: ^4.9.0 validators: ^3.0.0 path_provider: ^2.1.5 carousel_slider_plus: ^7.1.1 - flutter_form_builder: ^10.0.1 + flutter_form_builder: ^10.1.0 image_picker: ^1.1.2 flutter_typeahead: ^5.2.0 go_router: ^16.0.0 keyboard_dismisser: ^3.0.0 - retrofit: ^4.5.0 - get_it: ^8.0.3 + retrofit: ^4.7.0 + get_it: ^8.1.0 dio: ^5.8.0+1 dart_pusher_channels: ^1.2.3 photo_view: ^0.15.0 dismissible_page: ^1.0.2 - url_launcher: ^6.3.1 + url_launcher: ^6.3.2 easy_debounce: ^2.0.3 badges: ^3.1.2 google_fonts: ^6.2.1 - syncfusion_flutter_charts: ^30.1.38 - syncfusion_flutter_gauges: ^30.1.38 + syncfusion_flutter_charts: ^30.1.42 + syncfusion_flutter_gauges: ^30.1.42 table_calendar: ^3.2.0 flutter_keyboard_visibility: ^6.0.0 share_plus: ^11.0.0 @@ -58,7 +58,7 @@ dependencies: http: ^1.4.0 flutter_native_splash: ^2.4.6 webview_flutter: ^4.13.0 - sentry_flutter: ^8.14.2 + sentry_flutter: ^9.5.0 connectivity_plus: ^6.1.4 visibility_detector: ^0.4.0+2 firebase_core: ^4.0.0 @@ -70,15 +70,15 @@ dependencies: version: ^3.0.2 package_info_plus: ^8.3.0 device_info_plus: ^11.5.0 - permission_handler: ^12.0.0+1 + permission_handler: ^12.0.1 qr_code_scanner_plus: ^2.0.10+1 dev_dependencies: - build_runner: ^2.5.4 - freezed: ^3.0.6 - json_serializable: ^6.9.5 + build_runner: ^2.6.0 + freezed: ^3.2.0 + json_serializable: ^6.10.0 retrofit_generator: ^10.0.1 - mockito: ^5.4.6 + mockito: ^5.5.0 flutter_test: sdk: flutter From 3e7202d65e541e608223724a0af2589bae8c4368 Mon Sep 17 00:00:00 2001 From: mso7nueh Date: Fri, 1 Aug 2025 14:28:04 +0300 Subject: [PATCH 8/8] upd ver --- ios/Runner.xcodeproj/project.pbxproj | 6 +++--- ios/Runner/Info.plist | 2 +- pubspec.yaml | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index 23adc916..9a27847e 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -396,7 +396,7 @@ CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; CODE_SIGN_IDENTITY = "Apple Distribution: ITVIO, OOO (VL68C36HYS)"; CODE_SIGN_STYLE = Manual; - CURRENT_PROJECT_VERSION = 62; + CURRENT_PROJECT_VERSION = 64; DEVELOPMENT_TEAM = VL68C36HYS; ENABLE_BITCODE = NO; FRAMEWORK_SEARCH_PATHS = ( @@ -546,7 +546,7 @@ CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; CODE_SIGN_IDENTITY = "Apple Distribution: ITVIO, OOO (VL68C36HYS)"; CODE_SIGN_STYLE = Manual; - CURRENT_PROJECT_VERSION = 62; + CURRENT_PROJECT_VERSION = 64; DEVELOPMENT_TEAM = VL68C36HYS; ENABLE_BITCODE = NO; FRAMEWORK_SEARCH_PATHS = ( @@ -584,7 +584,7 @@ CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; CODE_SIGN_IDENTITY = "Apple Distribution: ITVIO, OOO (VL68C36HYS)"; CODE_SIGN_STYLE = Manual; - CURRENT_PROJECT_VERSION = 62; + CURRENT_PROJECT_VERSION = 64; DEVELOPMENT_TEAM = VL68C36HYS; ENABLE_BITCODE = NO; FRAMEWORK_SEARCH_PATHS = ( diff --git a/ios/Runner/Info.plist b/ios/Runner/Info.plist index f5570627..2341e63f 100644 --- a/ios/Runner/Info.plist +++ b/ios/Runner/Info.plist @@ -21,7 +21,7 @@ CFBundleSignature ???? CFBundleVersion - 62 + 64 ITSAppUsesNonExemptEncryption LSRequiresIPhoneOS diff --git a/pubspec.yaml b/pubspec.yaml index fe27d891..057a2d2d 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: eatvio_app description: A new Flutter project. -version: 1.2.6+60 +version: 1.2.6+64 publish_to: 'none' environment: