Merge pull request 'fix(recipe): tags error, feat(diet): add editing' (#457) from mso7nueh/eatvio_app:main into main

Reviewed-on: eatvio/eatvio_app#457
This commit is contained in:
mso7nueh
2025-05-23 09:04:36 +00:00
119 changed files with 1117 additions and 910 deletions

View File

@@ -388,7 +388,7 @@
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
CODE_SIGN_IDENTITY = "Apple Distribution: ITVIO, OOO (VL68C36HYS)"; CODE_SIGN_IDENTITY = "Apple Distribution: ITVIO, OOO (VL68C36HYS)";
CODE_SIGN_STYLE = Manual; CODE_SIGN_STYLE = Manual;
CURRENT_PROJECT_VERSION = 15; CURRENT_PROJECT_VERSION = 16;
DEVELOPMENT_TEAM = VL68C36HYS; DEVELOPMENT_TEAM = VL68C36HYS;
ENABLE_BITCODE = NO; ENABLE_BITCODE = NO;
FRAMEWORK_SEARCH_PATHS = ( FRAMEWORK_SEARCH_PATHS = (
@@ -538,7 +538,7 @@
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
CODE_SIGN_IDENTITY = "Apple Distribution: ITVIO, OOO (VL68C36HYS)"; CODE_SIGN_IDENTITY = "Apple Distribution: ITVIO, OOO (VL68C36HYS)";
CODE_SIGN_STYLE = Manual; CODE_SIGN_STYLE = Manual;
CURRENT_PROJECT_VERSION = 15; CURRENT_PROJECT_VERSION = 16;
DEVELOPMENT_TEAM = VL68C36HYS; DEVELOPMENT_TEAM = VL68C36HYS;
ENABLE_BITCODE = NO; ENABLE_BITCODE = NO;
FRAMEWORK_SEARCH_PATHS = ( FRAMEWORK_SEARCH_PATHS = (
@@ -576,7 +576,7 @@
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
CODE_SIGN_IDENTITY = "Apple Distribution: ITVIO, OOO (VL68C36HYS)"; CODE_SIGN_IDENTITY = "Apple Distribution: ITVIO, OOO (VL68C36HYS)";
CODE_SIGN_STYLE = Manual; CODE_SIGN_STYLE = Manual;
CURRENT_PROJECT_VERSION = 15; CURRENT_PROJECT_VERSION = 16;
DEVELOPMENT_TEAM = VL68C36HYS; DEVELOPMENT_TEAM = VL68C36HYS;
ENABLE_BITCODE = NO; ENABLE_BITCODE = NO;
FRAMEWORK_SEARCH_PATHS = ( FRAMEWORK_SEARCH_PATHS = (

View File

@@ -21,7 +21,7 @@
<key>CFBundleSignature</key> <key>CFBundleSignature</key>
<string>????</string> <string>????</string>
<key>CFBundleVersion</key> <key>CFBundleVersion</key>
<string>15</string> <string>16</string>
<key>ITSAppUsesNonExemptEncryption</key> <key>ITSAppUsesNonExemptEncryption</key>
<false/> <false/>
<key>LSRequiresIPhoneOS</key> <key>LSRequiresIPhoneOS</key>

View File

@@ -43,7 +43,7 @@ import 'package:eatvio_app/features/profile/presentation/pages/subs_screen.dart'
import 'package:eatvio_app/features/recipe/presentation/about_recipe_screen.dart'; import 'package:eatvio_app/features/recipe/presentation/about_recipe_screen.dart';
import 'package:eatvio_app/features/create_recipe/presentation/pages/recipe_create_screen.dart'; import 'package:eatvio_app/features/create_recipe/presentation/pages/recipe_create_screen.dart';
import 'package:eatvio_app/features/registration/presentation/pages/registration_screen.dart'; import 'package:eatvio_app/features/registration/presentation/pages/registration_screen.dart';
import 'package:eatvio_app/features/registration/presentation/pages/webview_registration_screen.dart'; import 'package:eatvio_app/features/registration/presentation/pages/verify_screen.dart';
import 'package:eatvio_app/features/settings/entities/settings_entity.dart'; import 'package:eatvio_app/features/settings/entities/settings_entity.dart';
import 'package:eatvio_app/features/settings/presentation/pages/change_email_screen.dart'; import 'package:eatvio_app/features/settings/presentation/pages/change_email_screen.dart';
import 'package:eatvio_app/features/settings/presentation/pages/change_password_screen.dart'; import 'package:eatvio_app/features/settings/presentation/pages/change_password_screen.dart';
@@ -76,7 +76,7 @@ class AppRouter {
name: 'authScreen', name: 'authScreen',
builder: (context, state) => const AuthScreen(), builder: (context, state) => const AuthScreen(),
routes: [ routes: [
GoRoute(path: 'webView-registration-screen', name: 'webViewRegistrationScreen', builder: (context, state) => const WebViewRegistrationScreen()), // GoRoute(path: 'webView-registration-screen', name: 'webViewRegistrationScreen', builder: (context, state) => const WebViewRegistrationScreen()),
GoRoute(path: 'registration-screen', name: 'registrationScreen', builder: (context, state) => const RegistrationScreen()), GoRoute(path: 'registration-screen', name: 'registrationScreen', builder: (context, state) => const RegistrationScreen()),
], ],
), ),
@@ -342,6 +342,11 @@ class AppRouter {
); );
}, },
), ),
GoRoute(
path: '/verify-screen',
name: 'verifyScreen',
builder: (context, state) => VerifyScreen(passKey: state.extra as String),
),
], ],
); );
} }

View File

@@ -1,5 +1,5 @@
// String baseUrl = 'https://eatvio.ru'; String baseUrl = 'https://eatvio.ru';
String baseUrl = 'https://dev2.eatvio.com'; // String baseUrl = 'https://dev2.eatvio.com';
const List<int> durationValues = [7, 14, 21]; const List<int> durationValues = [7, 14, 21];

View File

@@ -3,7 +3,7 @@ import 'package:freezed_annotation/freezed_annotation.dart';
part 'selection_popup_model.freezed.dart'; part 'selection_popup_model.freezed.dart';
@freezed @freezed
class SelectionPopupModel with _$SelectionPopupModel { abstract class SelectionPopupModel with _$SelectionPopupModel {
const factory SelectionPopupModel({ const factory SelectionPopupModel({
int? id, int? id,
required String title, required String title,

View File

@@ -0,0 +1,29 @@
import 'package:dio/dio.dart';
import 'package:eatvio_app/core/app_router.dart';
import 'package:eatvio_app/core/locator_service.dart';
import 'package:eatvio_app/features/profile/repositories/profile_repository.dart';
import 'package:go_router/go_router.dart';
class PhoneVerifyErrorInterceptor extends Interceptor {
@override
void onError(DioException err, ErrorInterceptorHandler handler) async {
if (err.response?.statusCode == 405) {
final data = err.response?.data;
if (data is Map<String, dynamic> && data['type'] == 'unverificated_phone') {
final String phone = await sl<ProfileRepository>().getMyPhone();
final String passKey = await sl<ProfileRepository>().getPassKey(phone);
AppRouter.navigatorKey.currentContext?.pushNamed('verifyScreen', extra: passKey);
return handler.reject(
DioException(
requestOptions: err.requestOptions,
response: err.response,
error: 'Phone number not verified',
type: DioExceptionType.badResponse,
),
);
}
}
return handler.next(err);
}
}

View File

@@ -1,5 +1,6 @@
import 'package:dio/dio.dart'; import 'package:dio/dio.dart';
import 'package:eatvio_app/core/const.dart'; import 'package:eatvio_app/core/const.dart';
import 'package:eatvio_app/core/dio/phone_verify_error_interceptor.dart';
import 'package:eatvio_app/core/interceptors/token_interceptor.dart'; import 'package:eatvio_app/core/interceptors/token_interceptor.dart';
import 'package:eatvio_app/core/websockets/ws_manager.dart'; import 'package:eatvio_app/core/websockets/ws_manager.dart';
import 'package:eatvio_app/core/websockets/ws_service.dart'; import 'package:eatvio_app/core/websockets/ws_service.dart';
@@ -191,7 +192,20 @@ Future<void> init() async {
// External // External
sl.registerLazySingleton( sl.registerLazySingleton(
() => Dio(BaseOptions(baseUrl: baseUrl, headers: {'accept': 'application/json', 'content-type': 'application/json'}))..interceptors.add(TokenInterceptor()), () => Dio(
BaseOptions(
baseUrl: baseUrl,
headers: {
'accept': 'application/json',
'content-type': 'application/json',
},
),
)..interceptors.addAll(
[
TokenInterceptor(),
PhoneVerifyErrorInterceptor(),
],
),
); );
sl.registerLazySingleton(() async => const FlutterSecureStorage()); sl.registerLazySingleton(() async => const FlutterSecureStorage());
} }

View File

@@ -4,7 +4,7 @@ part 'pagination_model.freezed.dart';
part 'pagination_model.g.dart'; part 'pagination_model.g.dart';
@freezed @freezed
class Links with _$Links { abstract class Links with _$Links {
const factory Links({ const factory Links({
@JsonKey(name: "first") required String first, @JsonKey(name: "first") required String first,
@JsonKey(name: "last") required String last, @JsonKey(name: "last") required String last,
@@ -16,7 +16,7 @@ class Links with _$Links {
} }
@freezed @freezed
class Meta with _$Meta { abstract class Meta with _$Meta {
const factory Meta({ const factory Meta({
@JsonKey(name: "current_page") required int currentPage, @JsonKey(name: "current_page") required int currentPage,
@JsonKey(name: "from") required dynamic from, @JsonKey(name: "from") required dynamic from,
@@ -34,7 +34,7 @@ class Meta with _$Meta {
} }
@freezed @freezed
class Link with _$Link { abstract class Link with _$Link {
const factory Link({ const factory Link({
@JsonKey(name: "url") String? url, @JsonKey(name: "url") String? url,
@JsonKey(name: "label") String? label, @JsonKey(name: "label") String? label,

View File

@@ -6,7 +6,9 @@ import 'package:eatvio_app/core/utils/toasts.dart';
import 'package:eatvio_app/core/widgets/show_error_dialog.dart'; import 'package:eatvio_app/core/widgets/show_error_dialog.dart';
import 'package:eatvio_app/features/blog_post_create/bloc/blog_post_create_cubit/blog_post_create_cubit.dart'; import 'package:eatvio_app/features/blog_post_create/bloc/blog_post_create_cubit/blog_post_create_cubit.dart';
import 'package:eatvio_app/features/complaining/presentation/complaining_bottom_sheet.dart'; import 'package:eatvio_app/features/complaining/presentation/complaining_bottom_sheet.dart';
import 'package:eatvio_app/features/create_diet/presentation/create_diet_screen.dart';
import 'package:eatvio_app/features/create_recipe/presentation/pages/recipe_create_screen.dart'; import 'package:eatvio_app/features/create_recipe/presentation/pages/recipe_create_screen.dart';
import 'package:eatvio_app/features/feed/models/diets_pagination_model.dart';
import 'package:eatvio_app/features/feed/models/feed_blog_post_model.dart'; import 'package:eatvio_app/features/feed/models/feed_blog_post_model.dart';
import 'package:eatvio_app/features/feed/models/recipes_model.dart'; import 'package:eatvio_app/features/feed/models/recipes_model.dart';
import 'package:eatvio_app/features/feed/presentation/bloc/diets_cubit/diets_cubit.dart'; import 'package:eatvio_app/features/feed/presentation/bloc/diets_cubit/diets_cubit.dart';
@@ -28,6 +30,7 @@ class CustomPopup extends StatelessWidget {
final int? id; final int? id;
final FeedBlogPostModel? feedBlogPostModel; final FeedBlogPostModel? feedBlogPostModel;
final Recipe? recipe; final Recipe? recipe;
final Diet? diet;
const CustomPopup({ const CustomPopup({
super.key, super.key,
@@ -38,6 +41,7 @@ class CustomPopup extends StatelessWidget {
this.slug, this.slug,
this.feedBlogPostModel, this.feedBlogPostModel,
this.recipe, this.recipe,
this.diet,
}); });
@override @override
@@ -87,18 +91,25 @@ class CustomPopup extends StatelessWidget {
}); });
addItem('assets/icons/share2.svg', 'Поделиться', () { addItem('assets/icons/share2.svg', 'Поделиться', () {
final box = context.findRenderObject() as RenderBox?; final box = context.findRenderObject() as RenderBox?;
Share.shareUri( SharePlus.instance.share(
Uri.parse( ShareParams(
'$baseUrl/ru/$path', uri: Uri.parse(
'$baseUrl/ru/$path',
),
sharePositionOrigin: box!.localToGlobal(Offset.zero) & box.size,
), ),
sharePositionOrigin: box!.localToGlobal(Offset.zero) & box.size,
); );
}); });
addItem('assets/icons/edit_paint.svg', 'Редактировать', () { addItem('assets/icons/edit_paint.svg', 'Редактировать', () async {
if (complainedContentType == ComplainedContent.posts) { if (complainedContentType == ComplainedContent.posts) {
GoRouter.of(context).pushNamed('blogPostCreateScreen', extra: feedBlogPostModel); GoRouter.of(context).pushNamed('blogPostCreateScreen', extra: feedBlogPostModel);
} else if (complainedContentType == ComplainedContent.recipe) { } else if (complainedContentType == ComplainedContent.recipe) {
GoRouter.of(context).pushNamed(RecipeCreateScreen.name, extra: recipe); GoRouter.of(context).pushNamed(RecipeCreateScreen.name, extra: recipe);
} else if (complainedContentType == ComplainedContent.diet) {
await showErrorDialog(context,
title: 'Предупреждение', description: 'Диета будет перенесена в архив. Вы создаете новую диету на основе существующей.');
await sl<MyDietsCubit>().unpublishDiet(id!);
GoRouter.of(context).pushNamed(CreateDietScreen.name, extra: diet);
} else { } else {
showInfoToast('В разработке'); showInfoToast('В разработке');
return; return;
@@ -161,11 +172,13 @@ class CustomPopup extends StatelessWidget {
}); });
addItem('assets/icons/share2.svg', 'Поделиться', () { addItem('assets/icons/share2.svg', 'Поделиться', () {
final box = context.findRenderObject() as RenderBox?; final box = context.findRenderObject() as RenderBox?;
Share.shareUri( SharePlus.instance.share(
Uri.parse( ShareParams(
'$baseUrl/ru/$path', uri: Uri.parse(
'$baseUrl/ru/$path',
),
sharePositionOrigin: box!.localToGlobal(Offset.zero) & box.size,
), ),
sharePositionOrigin: box!.localToGlobal(Offset.zero) & box.size,
); );
}); });
addItem('assets/icons/complain.svg', 'Пожаловаться', () { addItem('assets/icons/complain.svg', 'Пожаловаться', () {

View File

@@ -5,8 +5,8 @@ import 'package:eatvio_app/generated/l10n.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart'; import 'package:go_router/go_router.dart';
void showErrorDialog(BuildContext context, {String? title, String? description}) { Future<void> showErrorDialog(BuildContext context, {String? title, String? description}) async {
showDialog<void>( return await showDialog<void>(
context: context, context: context,
barrierColor: Colors.transparent, barrierColor: Colors.transparent,
builder: (BuildContext context) { builder: (BuildContext context) {

View File

@@ -5,7 +5,7 @@ part 'credentials_model.freezed.dart';
part 'credentials_model.g.dart'; part 'credentials_model.g.dart';
@freezed @freezed
class CredentialsModel with _$CredentialsModel { abstract class CredentialsModel with _$CredentialsModel {
const factory CredentialsModel({ const factory CredentialsModel({
required String email, required String email,
required String password, required String password,

View File

@@ -5,7 +5,7 @@ part 'token_model.freezed.dart';
part 'token_model.g.dart'; part 'token_model.g.dart';
@freezed @freezed
class TokenModel with _$TokenModel { abstract class TokenModel with _$TokenModel {
const factory TokenModel({ const factory TokenModel({
required String token, required String token,
}) = _TokenModel; }) = _TokenModel;

View File

@@ -3,7 +3,7 @@ import 'package:freezed_annotation/freezed_annotation.dart';
part 'auth_state.freezed.dart'; part 'auth_state.freezed.dart';
@freezed @freezed
class AuthState with _$AuthState { abstract class AuthState with _$AuthState {
const factory AuthState() = _AuthState; const factory AuthState() = _AuthState;
const factory AuthState.loading() = AuthStateLoading; const factory AuthState.loading() = AuthStateLoading;

View File

@@ -119,7 +119,7 @@ class _AuthScreenState extends State<AuthScreen> {
children: [ children: [
const Text('Нет аккаунта? '), const Text('Нет аккаунта? '),
GestureDetector( GestureDetector(
onTap: () => GoRouter.of(context).goNamed('webViewRegistrationScreen'), onTap: () => GoRouter.of(context).goNamed('registrationScreen'),
child: Text( child: Text(
'Зарегистрироваться', 'Зарегистрироваться',
style: TextStyle( style: TextStyle(

View File

@@ -242,9 +242,11 @@ class _BlogPostScreenState extends State<BlogPostScreen> {
icon: Icons.reply_rounded, icon: Icons.reply_rounded,
onTap: () { onTap: () {
final box = context.findRenderObject() as RenderBox?; final box = context.findRenderObject() as RenderBox?;
Share.shareUri( SharePlus.instance.share(
Uri.parse('$baseUrl/ru/blog_post/${widget.blogPost.id}'), ShareParams(
sharePositionOrigin: box!.localToGlobal(Offset.zero) & box.size, uri: Uri.parse('$baseUrl/ru/blog_post/${widget.blogPost.id}'),
sharePositionOrigin: box!.localToGlobal(Offset.zero) & box.size,
),
); );
}, },
), ),

View File

@@ -5,7 +5,7 @@ part '../../../presentation/feed/blog_post_create_screen/models/blog_post_create
part '../../../presentation/feed/blog_post_create_screen/models/blog_post_create_credentials_model.g.dart'; part '../../../presentation/feed/blog_post_create_screen/models/blog_post_create_credentials_model.g.dart';
@freezed @freezed
class BlogPostCreateCredentialsModel with _$BlogPostCreateCredentialsModel { abstract class BlogPostCreateCredentialsModel with _$BlogPostCreateCredentialsModel {
const factory BlogPostCreateCredentialsModel({ const factory BlogPostCreateCredentialsModel({
required String title, required String title,
required String description, required String description,

View File

@@ -5,7 +5,7 @@ part 'calendar_model.freezed.dart';
part 'calendar_model.g.dart'; part 'calendar_model.g.dart';
@freezed @freezed
class CalendarModel with _$CalendarModel { abstract class CalendarModel with _$CalendarModel {
const factory CalendarModel({ const factory CalendarModel({
required String date, required String date,
@JsonKey(name: 'is_current_day_included_in_the_chosen_diet_progression') required bool isCurrentDayIncludedInTheChosenDietProgression, @JsonKey(name: 'is_current_day_included_in_the_chosen_diet_progression') required bool isCurrentDayIncludedInTheChosenDietProgression,

View File

@@ -3,7 +3,7 @@ import 'package:freezed_annotation/freezed_annotation.dart';
part 'cancel_plan_state.freezed.dart'; part 'cancel_plan_state.freezed.dart';
@freezed @freezed
class CancelPlanState with _$CancelPlanState { abstract class CancelPlanState with _$CancelPlanState {
factory CancelPlanState() = _CancelPlanState; factory CancelPlanState() = _CancelPlanState;
} }

View File

@@ -4,7 +4,7 @@ part 'cancelation_model.freezed.dart';
part 'cancelation_model.g.dart'; part 'cancelation_model.g.dart';
@freezed @freezed
class CancelationModel with _$CancelationModel { abstract class CancelationModel with _$CancelationModel {
factory CancelationModel({ factory CancelationModel({
required String description, required String description,
required int price, required int price,

View File

@@ -5,7 +5,7 @@ part 'chat_message_model.freezed.dart';
part 'chat_message_model.g.dart'; part 'chat_message_model.g.dart';
@freezed @freezed
class ChatMessageModel with _$ChatMessageModel { abstract class ChatMessageModel with _$ChatMessageModel {
const factory ChatMessageModel({ const factory ChatMessageModel({
required int id, required int id,
required String data, required String data,

View File

@@ -6,7 +6,7 @@ part 'chat_messages_model.freezed.dart';
part 'chat_messages_model.g.dart'; part 'chat_messages_model.g.dart';
@freezed @freezed
class ChatMessagesModel with _$ChatMessagesModel { abstract class ChatMessagesModel with _$ChatMessagesModel {
const factory ChatMessagesModel({ const factory ChatMessagesModel({
@JsonKey(name: 'data') required List<ChatMessageModel> messagesList, @JsonKey(name: 'data') required List<ChatMessageModel> messagesList,
required ChatMetaModel meta, required ChatMetaModel meta,

View File

@@ -4,7 +4,7 @@ part 'chat_meta_model.freezed.dart';
part 'chat_meta_model.g.dart'; part 'chat_meta_model.g.dart';
@freezed @freezed
class ChatMetaModel with _$ChatMetaModel { abstract class ChatMetaModel with _$ChatMetaModel {
const factory ChatMetaModel({ const factory ChatMetaModel({
@JsonKey(name: "last_page") required int lastPage, @JsonKey(name: "last_page") required int lastPage,
}) = _ChatMetaModel; }) = _ChatMetaModel;

View File

@@ -7,7 +7,7 @@ part 'chat_room_model.freezed.dart';
part 'chat_room_model.g.dart'; part 'chat_room_model.g.dart';
@freezed @freezed
class ChatRoomModel with _$ChatRoomModel { abstract class ChatRoomModel with _$ChatRoomModel {
const factory ChatRoomModel({ const factory ChatRoomModel({
required String id, required String id,
@JsonKey(name: 'chat_room_setting') required ChatRoomSettingsModel chatRoomSettings, @JsonKey(name: 'chat_room_setting') required ChatRoomSettingsModel chatRoomSettings,
@@ -20,7 +20,7 @@ class ChatRoomModel with _$ChatRoomModel {
} }
@freezed @freezed
class Users with _$Users { abstract class Users with _$Users {
const factory Users({ const factory Users({
@JsonKey(name: 'from_chat_user') required ChatUserModel sender, @JsonKey(name: 'from_chat_user') required ChatUserModel sender,

View File

@@ -6,7 +6,7 @@ part 'chat_room_pagination_model.freezed.dart';
part 'chat_room_pagination_model.g.dart'; part 'chat_room_pagination_model.g.dart';
@freezed @freezed
class ChatRoomPaginationModel with _$ChatRoomPaginationModel { abstract class ChatRoomPaginationModel with _$ChatRoomPaginationModel {
const factory ChatRoomPaginationModel({ const factory ChatRoomPaginationModel({
@JsonKey(name: "chatRooms") required ChatRooms chatRooms, @JsonKey(name: "chatRooms") required ChatRooms chatRooms,
@JsonKey(name: "number_of_unread_chat_rooms") required int unreadChatsCount, @JsonKey(name: "number_of_unread_chat_rooms") required int unreadChatsCount,
@@ -16,7 +16,7 @@ class ChatRoomPaginationModel with _$ChatRoomPaginationModel {
} }
@freezed @freezed
class ChatRooms with _$ChatRooms { abstract class ChatRooms with _$ChatRooms {
const factory ChatRooms({ const factory ChatRooms({
@JsonKey(name: "data") required List<ChatRoom> data, @JsonKey(name: "data") required List<ChatRoom> data,
@JsonKey(name: "last_page") required int lastPage, @JsonKey(name: "last_page") required int lastPage,
@@ -27,7 +27,7 @@ class ChatRooms with _$ChatRooms {
} }
@freezed @freezed
class ChatRoom with _$ChatRoom { abstract class ChatRoom with _$ChatRoom {
const factory ChatRoom({ const factory ChatRoom({
@JsonKey(name: "id") required String id, @JsonKey(name: "id") required String id,
@JsonKey(name: "room_name") required String roomName, @JsonKey(name: "room_name") required String roomName,
@@ -48,7 +48,7 @@ ChatMessageModel? parseLastMessage(dynamic json) {
} }
@freezed @freezed
class Users with _$Users { abstract class Users with _$Users {
const factory Users({ const factory Users({
@JsonKey(name: "from_chat_user") required ChatUser fromChatUser, @JsonKey(name: "from_chat_user") required ChatUser fromChatUser,
@JsonKey(name: "to_chat_user") required ChatUser toChatUser, @JsonKey(name: "to_chat_user") required ChatUser toChatUser,
@@ -58,7 +58,7 @@ class Users with _$Users {
} }
@freezed @freezed
class ChatUser with _$ChatUser { abstract class ChatUser with _$ChatUser {
const factory ChatUser({ const factory ChatUser({
@JsonKey(name: "id") required int id, @JsonKey(name: "id") required int id,
@JsonKey(name: "name") required String name, @JsonKey(name: "name") required String name,

View File

@@ -4,7 +4,7 @@ part 'chat_room_settings_model.freezed.dart';
part 'chat_room_settings_model.g.dart'; part 'chat_room_settings_model.g.dart';
@freezed @freezed
class ChatRoomSettingsModel with _$ChatRoomSettingsModel { abstract class ChatRoomSettingsModel with _$ChatRoomSettingsModel {
const factory ChatRoomSettingsModel({ const factory ChatRoomSettingsModel({
required int id, required int id,
@JsonKey(name: 'room_name') required String roomName, @JsonKey(name: 'room_name') required String roomName,

View File

@@ -4,7 +4,7 @@ part 'chat_user_model.freezed.dart';
part 'chat_user_model.g.dart'; part 'chat_user_model.g.dart';
@freezed @freezed
class ChatUserModel with _$ChatUserModel { abstract class ChatUserModel with _$ChatUserModel {
const factory ChatUserModel({ const factory ChatUserModel({
required int id, required int id,
required String name, required String name,

View File

@@ -4,7 +4,7 @@ part 'payment_model.freezed.dart';
part 'payment_model.g.dart'; part 'payment_model.g.dart';
@freezed @freezed
class PaymentModel with _$PaymentModel { abstract class PaymentModel with _$PaymentModel {
factory PaymentModel({ factory PaymentModel({
@JsonKey(name: 'checkout_url') required String paymentUrl, @JsonKey(name: 'checkout_url') required String paymentUrl,

View File

@@ -4,7 +4,7 @@ part 'plan_complain_model.freezed.dart';
part 'plan_complain_model.g.dart'; part 'plan_complain_model.g.dart';
@freezed @freezed
class PlanComplainModel with _$PlanComplainModel { abstract class PlanComplainModel with _$PlanComplainModel {
factory PlanComplainModel({ factory PlanComplainModel({
@JsonKey(name: 'description') required String description, @JsonKey(name: 'description') required String description,

View File

@@ -4,7 +4,7 @@ part 'websocket_info_model.freezed.dart';
part 'websocket_info_model.g.dart'; part 'websocket_info_model.g.dart';
@freezed @freezed
class WebsocketInfoModel with _$WebsocketInfoModel { abstract class WebsocketInfoModel with _$WebsocketInfoModel {
const factory WebsocketInfoModel({ const factory WebsocketInfoModel({
required String key, required String key,
required String host, required String host,

View File

@@ -5,7 +5,7 @@ import 'package:freezed_annotation/freezed_annotation.dart';
part 'chats_state.freezed.dart'; part 'chats_state.freezed.dart';
@freezed @freezed
class ChatsState with _$ChatsState { abstract class ChatsState with _$ChatsState {
factory ChatsState({ factory ChatsState({
@Default(BaseState.initial) BaseState state, @Default(BaseState.initial) BaseState state,

View File

@@ -4,7 +4,7 @@ part 'complain_model.freezed.dart';
part 'complain_model.g.dart'; part 'complain_model.g.dart';
@freezed @freezed
class ComplainModel with _$ComplainModel { abstract class ComplainModel with _$ComplainModel {
const factory ComplainModel({ const factory ComplainModel({
@Default(null) String? description, @Default(null) String? description,

View File

@@ -6,7 +6,7 @@ import 'package:freezed_annotation/freezed_annotation.dart';
part 'complaining_state.freezed.dart'; part 'complaining_state.freezed.dart';
@freezed @freezed
class ComplainingState with _$ComplainingState { abstract class ComplainingState with _$ComplainingState {
factory ComplainingState({ factory ComplainingState({
@Default(false) bool isLoading, @Default(false) bool isLoading,

View File

@@ -5,7 +5,7 @@ part 'consultant_profile_model.freezed.dart';
part 'consultant_profile_model.g.dart'; part 'consultant_profile_model.g.dart';
@freezed @freezed
class ConsultantProfileModel with _$ConsultantProfileModel { abstract class ConsultantProfileModel with _$ConsultantProfileModel {
const factory ConsultantProfileModel({ const factory ConsultantProfileModel({
@JsonKey(name: 'has_medical_education', includeIfNull: false) bool? hasMedicalEducation, @JsonKey(name: 'has_medical_education', includeIfNull: false) bool? hasMedicalEducation,
@JsonKey(name: 'social_links', includeIfNull: false) SocialLinksModel? socialLinks, @JsonKey(name: 'social_links', includeIfNull: false) SocialLinksModel? socialLinks,
@@ -17,7 +17,7 @@ class ConsultantProfileModel with _$ConsultantProfileModel {
} }
@freezed @freezed
class SocialLinksModel with _$SocialLinksModel { abstract class SocialLinksModel with _$SocialLinksModel {
const factory SocialLinksModel({ const factory SocialLinksModel({
@JsonKey(name: 'vk_link', includeIfNull: false) String? vkLink, @JsonKey(name: 'vk_link', includeIfNull: false) String? vkLink,
@JsonKey(name: 'tg_link', includeIfNull: false) String? tgLink, @JsonKey(name: 'tg_link', includeIfNull: false) String? tgLink,
@@ -30,7 +30,7 @@ class SocialLinksModel with _$SocialLinksModel {
} }
@freezed @freezed
class CertificatesModel with _$CertificatesModel { abstract class CertificatesModel with _$CertificatesModel {
const factory CertificatesModel({ const factory CertificatesModel({
required String title, required String title,
required String date, required String date,

View File

@@ -6,7 +6,7 @@ part 'consultation_request_model.freezed.dart';
part 'consultation_request_model.g.dart'; part 'consultation_request_model.g.dart';
@freezed @freezed
class ConsultationRequestModel with _$ConsultationRequestModel { abstract class ConsultationRequestModel with _$ConsultationRequestModel {
const factory ConsultationRequestModel({ const factory ConsultationRequestModel({
@JsonKey(name: 'rating_place') required int ratingPlace, @JsonKey(name: 'rating_place') required int ratingPlace,
@JsonKey(name: 'education_resource') required EducationModel educationModel, @JsonKey(name: 'education_resource') required EducationModel educationModel,
@@ -17,7 +17,7 @@ class ConsultationRequestModel with _$ConsultationRequestModel {
} }
@freezed @freezed
class CertPhotosModel with _$CertPhotosModel { abstract class CertPhotosModel with _$CertPhotosModel {
const factory CertPhotosModel({ const factory CertPhotosModel({
required String url, required String url,
}) = _CertPhotosModel; }) = _CertPhotosModel;

View File

@@ -4,7 +4,7 @@ part 'rating_model.freezed.dart';
part 'rating_model.g.dart'; part 'rating_model.g.dart';
@freezed @freezed
class RatingModel with _$RatingModel { abstract class RatingModel with _$RatingModel {
factory RatingModel({ factory RatingModel({
required DateTime date, required DateTime date,

View File

@@ -6,7 +6,7 @@ part 'consultation_model.freezed.dart';
part 'consultation_model.g.dart'; part 'consultation_model.g.dart';
@freezed @freezed
class ConsultationModel with _$ConsultationModel { abstract class ConsultationModel with _$ConsultationModel {
factory ConsultationModel({ factory ConsultationModel({
required int id, required int id,
@JsonKey(name: 'last_state') required ChosenPlanStateEnum chosenPlanState, @JsonKey(name: 'last_state') required ChosenPlanStateEnum chosenPlanState,
@@ -26,7 +26,7 @@ class ConsultationModel with _$ConsultationModel {
} }
@freezed @freezed
class DiaryModel with _$DiaryModel { abstract class DiaryModel with _$DiaryModel {
factory DiaryModel({ factory DiaryModel({
required int id, required int id,
required DiaryStateEnum state, required DiaryStateEnum state,
@@ -58,7 +58,7 @@ enum DiaryStateEnum {
} }
@freezed @freezed
class ConsultationPaginationModel with _$ConsultationPaginationModel { abstract class ConsultationPaginationModel with _$ConsultationPaginationModel {
factory ConsultationPaginationModel({required List<ConsultationModel> data}) = _ConsultationPaginationModel; factory ConsultationPaginationModel({required List<ConsultationModel> data}) = _ConsultationPaginationModel;
factory ConsultationPaginationModel.fromJson(Map<String, dynamic> json) => _$ConsultationPaginationModelFromJson(json); factory ConsultationPaginationModel.fromJson(Map<String, dynamic> json) => _$ConsultationPaginationModelFromJson(json);

View File

@@ -5,7 +5,7 @@ import 'package:freezed_annotation/freezed_annotation.dart';
part 'consultations_state.freezed.dart'; part 'consultations_state.freezed.dart';
@freezed @freezed
class ConsultationsState with _$ConsultationsState { abstract class ConsultationsState with _$ConsultationsState {
factory ConsultationsState({ factory ConsultationsState({
@Default(BaseState.initial) BaseState state, @Default(BaseState.initial) BaseState state,

View File

@@ -5,7 +5,7 @@ import 'package:freezed_annotation/freezed_annotation.dart';
part 'create_diet_model.freezed.dart'; part 'create_diet_model.freezed.dart';
@freezed @freezed
class CreateDietModel with _$CreateDietModel { abstract class CreateDietModel with _$CreateDietModel {
const CreateDietModel._(); const CreateDietModel._();
const factory CreateDietModel({ const factory CreateDietModel({

View File

@@ -27,8 +27,11 @@ import 'package:go_router/go_router.dart';
class CreateDietScreen extends StatelessWidget { class CreateDietScreen extends StatelessWidget {
static const name = 'createDietScreen'; static const name = 'createDietScreen';
static const path = '/create-diet-screen'; static const path = '/create-diet-screen';
const CreateDietScreen({super.key, this.diet}); const CreateDietScreen({super.key, this.diet});
final Diet? diet; final Diet? diet;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return BlocProvider( return BlocProvider(
@@ -40,6 +43,7 @@ class CreateDietScreen extends StatelessWidget {
class CreateDietScreenContent extends StatefulWidget { class CreateDietScreenContent extends StatefulWidget {
const CreateDietScreenContent({super.key, this.diet}); const CreateDietScreenContent({super.key, this.diet});
final Diet? diet; final Diet? diet;
@override @override
@@ -95,7 +99,7 @@ class _CreateDietScreenContentState extends State<CreateDietScreenContent> {
appBar: AppBar( appBar: AppBar(
centerTitle: true, centerTitle: true,
title: Text( title: Text(
widget.diet != null ? 'Редактирование диеты' : s.create_diet, s.create_diet,
textAlign: TextAlign.center, textAlign: TextAlign.center,
overflow: TextOverflow.ellipsis, overflow: TextOverflow.ellipsis,
softWrap: true, softWrap: true,
@@ -151,7 +155,7 @@ class _CreateDietScreenContentState extends State<CreateDietScreenContent> {
const SizedBox(height: 12), const SizedBox(height: 12),
const DietDurationDropDownWidget(), const DietDurationDropDownWidget(),
const SizedBox(height: 12), const SizedBox(height: 12),
const StatusDropDownWidget(), StatusDropDownWidget(dietState: widget.diet?.state),
const SizedBox(height: 16), const SizedBox(height: 16),
const DietTypeChoiceWidget(), const DietTypeChoiceWidget(),
const SizedBox(height: 16), const SizedBox(height: 16),
@@ -247,23 +251,13 @@ class _CreateDietScreenContentState extends State<CreateDietScreenContent> {
else else
CustomOutlinedButton( CustomOutlinedButton(
onPressed: () async { onPressed: () async {
if (widget.diet != null) { final result = await context.read<CreateDietCubit>().createDiet();
final result = await context.read<CreateDietCubit>().updateDiet( if (result == 'error') {
widget.diet!.id, if (!context.mounted) return;
); showErrorDialog(context, title: '${s.could_not_publish_diet} ${state.dietData.name}');
if (result == 'error') {
if (!context.mounted) return;
showErrorDialog(context, title: '${s.could_not_update_diet} ${state.dietData.name}');
}
} else {
final result = await context.read<CreateDietCubit>().createDiet();
if (result == 'error') {
if (!context.mounted) return;
showErrorDialog(context, title: '${s.could_not_publish_diet} ${state.dietData.name}');
}
} }
}, },
text: widget.diet != null ? s.save : s.publish, text: s.publish,
height: 52, height: 52,
buttonTextStyle: TextStyles.textMSemibold.copyWith(color: appTheme.whiteA700), buttonTextStyle: TextStyles.textMSemibold.copyWith(color: appTheme.whiteA700),
buttonStyle: ButtonStyle( buttonStyle: ButtonStyle(

View File

@@ -12,6 +12,8 @@ import 'package:eatvio_app/features/glossary/repositories/glossary_repository.da
import 'package:eatvio_app/features/profile/repositories/profile_repository.dart'; import 'package:eatvio_app/features/profile/repositories/profile_repository.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_image_compress/flutter_image_compress.dart'; import 'package:flutter_image_compress/flutter_image_compress.dart';
import 'package:http/http.dart' as http;
import 'package:path_provider/path_provider.dart';
class CreateDietCubit extends Cubit<CreateDietState> { class CreateDietCubit extends Cubit<CreateDietState> {
final CreateDietRepository createDietRepository; final CreateDietRepository createDietRepository;
@@ -319,18 +321,38 @@ class CreateDietCubit extends Cubit<CreateDietState> {
return diet; return diet;
} }
Future<File> downloadImageAsFile(String imageUrl) async {
final response = await http.get(Uri.parse(imageUrl));
if (response.statusCode == 200) {
final tempDir = await getTemporaryDirectory();
final filePath = '${tempDir.path}/${imageUrl.split('/').last}';
final file = File(filePath);
return await file.writeAsBytes(response.bodyBytes);
} else {
throw Exception('Не удалось загрузить изображение');
}
}
Future<String?> createDiet() async { Future<String?> createDiet() async {
emit(state.copyWith(isDietPublishing: true)); emit(state.copyWith(isDietPublishing: true));
if (!_isFromValid()) return 'validation'; if (!_isFromValid()) return 'validation';
try { try {
final image = await ImageCompressUtility.compressFile(File(state.dietData.image!.path)); File? file;
if (state.dietData.imageUrl != null) {
file = await downloadImageAsFile(state.dietData.imageUrl!);
}
File? image;
if (state.dietData.image?.path != null) {
image = await ImageCompressUtility.compressFile(File(state.dietData.image!.path));
}
final dietState = state.dietData.state!; final dietState = state.dietData.state!;
final dailySchedule = state.dietData.dailySchedule; final dailySchedule = state.dietData.dailySchedule;
await createDietRepository.createDiet( await createDietRepository.createDiet(
name: state.dietData.name ?? '', name: state.dietData.name ?? '',
duration: state.dietData.duration ?? 7, duration: state.dietData.duration ?? 7,
state: dietState, state: dietState,
image: image, image: image ?? file!,
meatType: state.dietData.type['meat'] == true ? '1' : '0', meatType: state.dietData.type['meat'] == true ? '1' : '0',
carbType: state.dietData.type['carb'] == true ? '1' : '0', carbType: state.dietData.type['carb'] == true ? '1' : '0',
vegType: state.dietData.type['veg'] == true ? '1' : '0', vegType: state.dietData.type['veg'] == true ? '1' : '0',

View File

@@ -6,7 +6,7 @@ import 'package:freezed_annotation/freezed_annotation.dart';
part 'create_diet_state.freezed.dart'; part 'create_diet_state.freezed.dart';
@freezed @freezed
class CreateDietState with _$CreateDietState { abstract class CreateDietState with _$CreateDietState {
const factory CreateDietState({ const factory CreateDietState({
required bool isLoading, required bool isLoading,
required bool isDietPublishing, required bool isDietPublishing,

View File

@@ -127,11 +127,12 @@ class _DietImagePickerWidgetState extends State<DietImagePickerWidget> {
: Stack( : Stack(
children: [ children: [
DottedBorder( DottedBorder(
stackFit: StackFit.expand, options: RoundedRectDottedBorderOptions(
dashPattern: const [14, 14], stackFit: StackFit.expand,
color: state.dietImageError != null ? appTheme.red : appTheme.dottedBorder, dashPattern: const [14, 14],
borderType: BorderType.RRect, color: state.dietImageError != null ? appTheme.red : appTheme.dottedBorder,
radius: const Radius.circular(12), radius: const Radius.circular(12),
),
child: const SizedBox.expand(), child: const SizedBox.expand(),
), ),
Center( Center(

View File

@@ -11,7 +11,9 @@ import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:collection/collection.dart'; import 'package:collection/collection.dart';
class StatusDropDownWidget extends StatefulWidget { class StatusDropDownWidget extends StatefulWidget {
const StatusDropDownWidget({super.key}); final DietState? dietState;
const StatusDropDownWidget({super.key, this.dietState});
@override @override
State<StatusDropDownWidget> createState() => _StatusDropDownWidgetState(); State<StatusDropDownWidget> createState() => _StatusDropDownWidgetState();
@@ -19,6 +21,7 @@ class StatusDropDownWidget extends StatefulWidget {
class _StatusDropDownWidgetState extends State<StatusDropDownWidget> { class _StatusDropDownWidgetState extends State<StatusDropDownWidget> {
final List<String> dietStateTitles = []; final List<String> dietStateTitles = [];
String? currentState;
// late final List<DietState> dietStates = DietState.values; // late final List<DietState> dietStates = DietState.values;
@override @override
@@ -39,6 +42,13 @@ class _StatusDropDownWidgetState extends State<StatusDropDownWidget> {
// } // }
// } // }
} }
if (widget.dietState != null) {
if (widget.dietState == DietState.active) {
currentState = dietStateTitles[0];
} else if (widget.dietState == DietState.personal) {
currentState = dietStateTitles[1];
}
}
} }
@override @override
@@ -77,7 +87,7 @@ class _StatusDropDownWidgetState extends State<StatusDropDownWidget> {
), ),
) )
.toList(), .toList(),
value: state.dietState == DietState.active ? dietStateTitles[0] : state.dietState == DietState.personal ? dietStateTitles[1] : null, value: currentState,
), ),
if (state.dietStateError != null) ...[ if (state.dietStateError != null) ...[
const SizedBox( const SizedBox(

View File

@@ -5,7 +5,7 @@ import 'package:freezed_annotation/freezed_annotation.dart';
part 'create_plan_model.freezed.dart'; part 'create_plan_model.freezed.dart';
@freezed @freezed
class CreatePlanModel with _$CreatePlanModel { abstract class CreatePlanModel with _$CreatePlanModel {
const CreatePlanModel._(); const CreatePlanModel._();
const factory CreatePlanModel({ const factory CreatePlanModel({

View File

@@ -4,7 +4,7 @@ part 'plan_slug_model.freezed.dart';
part 'plan_slug_model.g.dart'; part 'plan_slug_model.g.dart';
@freezed @freezed
class PlanSlugModel with _$PlanSlugModel { abstract class PlanSlugModel with _$PlanSlugModel {
factory PlanSlugModel({@JsonKey(name: 'slug') required String slug}) = _PlanSlugModel; factory PlanSlugModel({@JsonKey(name: 'slug') required String slug}) = _PlanSlugModel;
factory PlanSlugModel.fromJson(Map<String, dynamic> json) => _$PlanSlugModelFromJson(json); factory PlanSlugModel.fromJson(Map<String, dynamic> json) => _$PlanSlugModelFromJson(json);

View File

@@ -5,7 +5,7 @@ import 'package:freezed_annotation/freezed_annotation.dart';
part 'create_plan_state.freezed.dart'; part 'create_plan_state.freezed.dart';
@freezed @freezed
class CreatePlanState with _$CreatePlanState { abstract class CreatePlanState with _$CreatePlanState {
const factory CreatePlanState({ const factory CreatePlanState({
required bool isLoading, required bool isLoading,
required String? errorMessage, required String? errorMessage,
@@ -29,7 +29,7 @@ class CreatePlanState with _$CreatePlanState {
} }
@freezed @freezed
class PlanValidationState with _$PlanValidationState { abstract class PlanValidationState with _$PlanValidationState {
factory PlanValidationState({ factory PlanValidationState({
required bool titleHasError, required bool titleHasError,
required bool durationHasError, required bool durationHasError,
@@ -54,7 +54,7 @@ class PlanValidationState with _$PlanValidationState {
} }
@freezed @freezed
class OptionValidationState with _$OptionValidationState { abstract class OptionValidationState with _$OptionValidationState {
factory OptionValidationState({ factory OptionValidationState({
required bool titleHasError, required bool titleHasError,
required bool priceHasError, required bool priceHasError,

View File

@@ -116,11 +116,12 @@ class _PlanImagePickerWidgetState extends State<PlanImagePickerWidget> {
: Stack( : Stack(
children: [ children: [
DottedBorder( DottedBorder(
stackFit: StackFit.expand, options: RoundedRectDottedBorderOptions(
dashPattern: const [14, 14], stackFit: StackFit.expand,
color: state.validationState.imageHasError ? appTheme.red : appTheme.dottedBorder, dashPattern: const [14, 14],
borderType: BorderType.RRect, color: state.validationState.imageHasError ? appTheme.red : appTheme.dottedBorder,
radius: const Radius.circular(12), radius: const Radius.circular(12),
),
child: const SizedBox.expand(), child: const SizedBox.expand(),
), ),
Center( Center(

View File

@@ -99,7 +99,7 @@ enum TypeOfRecipe {
} }
@freezed @freezed
class RecipeCreateEntity with _$RecipeCreateEntity { abstract class RecipeCreateEntity with _$RecipeCreateEntity {
const RecipeCreateEntity._(); const RecipeCreateEntity._();
const factory RecipeCreateEntity({ const factory RecipeCreateEntity({
@@ -138,7 +138,7 @@ class RecipeCreateEntity with _$RecipeCreateEntity {
} }
@freezed @freezed
class StepEntity with _$StepEntity { abstract class StepEntity with _$StepEntity {
const StepEntity._(); const StepEntity._();
const factory StepEntity({ const factory StepEntity({

View File

@@ -5,7 +5,7 @@ part 'ingredient.freezed.dart';
part 'ingredient.g.dart'; part 'ingredient.g.dart';
@freezed @freezed
class Ingredient with _$Ingredient { abstract class Ingredient with _$Ingredient {
const factory Ingredient({ const factory Ingredient({
required String name, required String name,
required String unit, required String unit,

View File

@@ -5,7 +5,7 @@ part 'product.freezed.dart';
part 'product.g.dart'; part 'product.g.dart';
@freezed @freezed
class Product with _$Product { abstract class Product with _$Product {
const factory Product({ const factory Product({
required int id, required int id,
required String name, required String name,

View File

@@ -17,7 +17,7 @@ enum RecipeType {
} }
@freezed @freezed
class RecipeCreateModel with _$RecipeCreateModel { abstract class RecipeCreateModel with _$RecipeCreateModel {
const factory RecipeCreateModel({ const factory RecipeCreateModel({
required String title, required String title,
required String state, required String state,

View File

@@ -7,7 +7,7 @@ part 'recipe_model.freezed.dart';
part 'recipe_model.g.dart'; part 'recipe_model.g.dart';
@freezed @freezed
class RecipeModel with _$RecipeModel { abstract class RecipeModel with _$RecipeModel {
const factory RecipeModel({ const factory RecipeModel({
List<Ingredient?>? ingredients, List<Ingredient?>? ingredients,
List<Step?>? steps, List<Step?>? steps,

View File

@@ -6,7 +6,7 @@ part 'recipe_tag_model.freezed.dart';
part 'recipe_tag_model.g.dart'; part 'recipe_tag_model.g.dart';
@freezed @freezed
class RecipeTagModel with _$RecipeTagModel { abstract class RecipeTagModel with _$RecipeTagModel {
const factory RecipeTagModel({ const factory RecipeTagModel({
@JsonKey(name: "data") required List<RecipeTag> data, @JsonKey(name: "data") required List<RecipeTag> data,
@JsonKey(name: "links") required Links links, @JsonKey(name: "links") required Links links,
@@ -17,7 +17,7 @@ class RecipeTagModel with _$RecipeTagModel {
} }
@freezed @freezed
class RecipeTag with _$RecipeTag { abstract class RecipeTag with _$RecipeTag {
const factory RecipeTag({ const factory RecipeTag({
@JsonKey(name: "id") required int id, @JsonKey(name: "id") required int id,
@JsonKey(name: "name") required String name, @JsonKey(name: "name") required String name,

View File

@@ -5,7 +5,7 @@ part 'step.freezed.dart';
part 'step.g.dart'; part 'step.g.dart';
@freezed @freezed
class Step with _$Step { abstract class Step with _$Step {
const factory Step({ const factory Step({
String? image, String? image,
String? description, String? description,

View File

@@ -4,7 +4,7 @@ import 'package:freezed_annotation/freezed_annotation.dart';
part 'create_recipe_state.freezed.dart'; part 'create_recipe_state.freezed.dart';
@freezed @freezed
class CreateRecipeState with _$CreateRecipeState { abstract class CreateRecipeState with _$CreateRecipeState {
const factory CreateRecipeState({ const factory CreateRecipeState({
required RecipeCreateEntity entity, required RecipeCreateEntity entity,
required bool loading, required bool loading,

View File

@@ -1,6 +1,7 @@
import 'package:eatvio_app/core/theme/theme_helper.dart'; import 'package:eatvio_app/core/theme/theme_helper.dart';
import 'package:eatvio_app/core/widgets/custom_text_form_field.dart'; import 'package:eatvio_app/core/widgets/custom_text_form_field.dart';
import 'package:eatvio_app/features/create_recipe/presentation/bloc/create_recipe_cubit/create_recipe_cubit.dart'; import 'package:eatvio_app/features/create_recipe/presentation/bloc/create_recipe_cubit/create_recipe_cubit.dart';
import 'package:eatvio_app/features/create_recipe/presentation/bloc/create_recipe_cubit/create_recipe_state.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
@@ -14,79 +15,73 @@ class TagsWidget extends StatefulWidget {
class _TagsWidgetState extends State<TagsWidget> { class _TagsWidgetState extends State<TagsWidget> {
late final CreateRecipeCubit createRecipeCubit; late final CreateRecipeCubit createRecipeCubit;
final tagController = TextEditingController(); final tagController = TextEditingController();
late final List<String> tags;
@override
void initState() {
super.initState();
createRecipeCubit = context.read<CreateRecipeCubit>();
tags = createRecipeCubit.state.entity.tags;
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Column( return BlocBuilder<CreateRecipeCubit, CreateRecipeState>(
crossAxisAlignment: CrossAxisAlignment.start, builder: (BuildContext context, CreateRecipeState state) {
children: [ return Column(
const Text('Теги'), crossAxisAlignment: CrossAxisAlignment.start,
const SizedBox(height: 4),
CustomTextFormField(
hintText: 'Например: без майонеза',
controller: tagController,
suffix: IconButton(
onPressed: () {
if (tagController.text.isNotEmpty) {
setState(() {
tags.add(tagController.text);
tagController.clear();
});
}
},
icon: Icon(
Icons.done,
color: appTheme.blueA400,
),
),
),
const SizedBox(height: 12),
Wrap(
spacing: 8,
runSpacing: 8,
children: [ children: [
for (int i = 0; i < tags.length; i++) ...[ const Text('Теги'),
InkWell( const SizedBox(height: 4),
onTap: () { CustomTextFormField(
setState(() { hintText: 'Например: без майонеза',
tags.remove(tags[i]); controller: tagController,
}); suffix: IconButton(
onPressed: () {
if (tagController.text.isNotEmpty) {
context.read<CreateRecipeCubit>().addTag(tagController.text);
setState(() {
tagController.clear();
});
}
}, },
borderRadius: BorderRadius.circular(16), icon: Icon(
child: Ink( Icons.done,
padding: const EdgeInsets.symmetric(vertical: 4, horizontal: 12), color: appTheme.blueA400,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(16),
color: Colors.grey.shade200,
),
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
Text(
tags[i],
),
const SizedBox(width: 4),
Icon(
Icons.delete_outline_rounded,
color: Colors.grey.shade600,
size: 20,
),
],
),
), ),
), ),
], ),
const SizedBox(height: 12),
Wrap(
spacing: 8,
runSpacing: 8,
children: [
for (int i = 0; i < state.entity.tags.length; i++) ...[
InkWell(
onTap: () {
context.read<CreateRecipeCubit>().removeTag(state.entity.tags[i]);
},
borderRadius: BorderRadius.circular(16),
child: Ink(
padding: const EdgeInsets.symmetric(vertical: 4, horizontal: 12),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(16),
color: Colors.grey.shade200,
),
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
Text(
state.entity.tags[i],
),
const SizedBox(width: 4),
Icon(
Icons.delete_outline_rounded,
color: Colors.grey.shade600,
size: 20,
),
],
),
),
),
],
],
),
], ],
), );
], },
); );
} }
} }

View File

@@ -4,7 +4,7 @@ part 'consultant_comment_model.freezed.dart';
part 'consultant_comment_model.g.dart'; part 'consultant_comment_model.g.dart';
@freezed @freezed
class ConsultantCommentModel with _$ConsultantCommentModel { abstract class ConsultantCommentModel with _$ConsultantCommentModel {
factory ConsultantCommentModel({ factory ConsultantCommentModel({
String? comment, String? comment,
@Default({}) @JsonKey(name: 'meals') Map<String, MealCommentModel> mealsComments, @Default({}) @JsonKey(name: 'meals') Map<String, MealCommentModel> mealsComments,
@@ -15,7 +15,7 @@ class ConsultantCommentModel with _$ConsultantCommentModel {
} }
@freezed @freezed
class PortionCommentModel with _$PortionCommentModel { abstract class PortionCommentModel with _$PortionCommentModel {
factory PortionCommentModel({ factory PortionCommentModel({
required String comment, required String comment,
required int id, required int id,
@@ -25,7 +25,7 @@ class PortionCommentModel with _$PortionCommentModel {
} }
@freezed @freezed
class MealCommentModel with _$MealCommentModel { abstract class MealCommentModel with _$MealCommentModel {
factory MealCommentModel({ factory MealCommentModel({
required String comment, required String comment,

View File

@@ -4,7 +4,7 @@ part 'consultant_review_model.freezed.dart';
part 'consultant_review_model.g.dart'; part 'consultant_review_model.g.dart';
@freezed @freezed
class ConsultantReviewModel with _$ConsultantReviewModel { abstract class ConsultantReviewModel with _$ConsultantReviewModel {
factory ConsultantReviewModel({ factory ConsultantReviewModel({
required String planName, required String planName,
@@ -18,7 +18,7 @@ class ConsultantReviewModel with _$ConsultantReviewModel {
@freezed @freezed
class ConsultantComments with _$ConsultantComments { abstract class ConsultantComments with _$ConsultantComments {
factory ConsultantComments({ factory ConsultantComments({
required String? dayComment, required String? dayComment,
@@ -32,7 +32,7 @@ class ConsultantComments with _$ConsultantComments {
@freezed @freezed
class MealComment with _$MealComment { abstract class MealComment with _$MealComment {
factory MealComment({ factory MealComment({
required String comment, required String comment,
@@ -43,7 +43,7 @@ class MealComment with _$MealComment {
} }
@freezed @freezed
class PortionComment with _$PortionComment { abstract class PortionComment with _$PortionComment {
factory PortionComment({ factory PortionComment({
@JsonKey(name: 'id') required int portionId, @JsonKey(name: 'id') required int portionId,

File diff suppressed because it is too large Load Diff

View File

@@ -6,9 +6,9 @@ part of 'consultant_review_model.dart';
// JsonSerializableGenerator // JsonSerializableGenerator
// ************************************************************************** // **************************************************************************
_$ConsultantReviewModelImpl _$$ConsultantReviewModelImplFromJson( _ConsultantReviewModel _$ConsultantReviewModelFromJson(
Map<String, dynamic> json) => Map<String, dynamic> json) =>
_$ConsultantReviewModelImpl( _ConsultantReviewModel(
planName: json['planName'] as String, planName: json['planName'] as String,
planDuration: (json['planDuration'] as num).toInt(), planDuration: (json['planDuration'] as num).toInt(),
currentPlanDay: (json['currentPlanDay'] as num).toInt(), currentPlanDay: (json['currentPlanDay'] as num).toInt(),
@@ -16,8 +16,8 @@ _$ConsultantReviewModelImpl _$$ConsultantReviewModelImplFromJson(
json['consultantComments'] as Map<String, dynamic>), json['consultantComments'] as Map<String, dynamic>),
); );
Map<String, dynamic> _$$ConsultantReviewModelImplToJson( Map<String, dynamic> _$ConsultantReviewModelToJson(
_$ConsultantReviewModelImpl instance) => _ConsultantReviewModel instance) =>
<String, dynamic>{ <String, dynamic>{
'planName': instance.planName, 'planName': instance.planName,
'planDuration': instance.planDuration, 'planDuration': instance.planDuration,
@@ -25,9 +25,8 @@ Map<String, dynamic> _$$ConsultantReviewModelImplToJson(
'consultantComments': instance.consultantComments, 'consultantComments': instance.consultantComments,
}; };
_$ConsultantCommentsImpl _$$ConsultantCommentsImplFromJson( _ConsultantComments _$ConsultantCommentsFromJson(Map<String, dynamic> json) =>
Map<String, dynamic> json) => _ConsultantComments(
_$ConsultantCommentsImpl(
dayComment: json['dayComment'] as String?, dayComment: json['dayComment'] as String?,
mealsComments: (json['mealsComments'] as List<dynamic>) mealsComments: (json['mealsComments'] as List<dynamic>)
.map((e) => MealComment.fromJson(e as Map<String, dynamic>)) .map((e) => MealComment.fromJson(e as Map<String, dynamic>))
@@ -37,34 +36,31 @@ _$ConsultantCommentsImpl _$$ConsultantCommentsImplFromJson(
.toList(), .toList(),
); );
Map<String, dynamic> _$$ConsultantCommentsImplToJson( Map<String, dynamic> _$ConsultantCommentsToJson(_ConsultantComments instance) =>
_$ConsultantCommentsImpl instance) =>
<String, dynamic>{ <String, dynamic>{
'dayComment': instance.dayComment, 'dayComment': instance.dayComment,
'mealsComments': instance.mealsComments, 'mealsComments': instance.mealsComments,
'portionsComments': instance.portionsComments, 'portionsComments': instance.portionsComments,
}; };
_$MealCommentImpl _$$MealCommentImplFromJson(Map<String, dynamic> json) => _MealComment _$MealCommentFromJson(Map<String, dynamic> json) => _MealComment(
_$MealCommentImpl(
comment: json['comment'] as String, comment: json['comment'] as String,
typeNo: (json['typeNo'] as num).toInt(), typeNo: (json['typeNo'] as num).toInt(),
); );
Map<String, dynamic> _$$MealCommentImplToJson(_$MealCommentImpl instance) => Map<String, dynamic> _$MealCommentToJson(_MealComment instance) =>
<String, dynamic>{ <String, dynamic>{
'comment': instance.comment, 'comment': instance.comment,
'typeNo': instance.typeNo, 'typeNo': instance.typeNo,
}; };
_$PortionCommentImpl _$$PortionCommentImplFromJson(Map<String, dynamic> json) => _PortionComment _$PortionCommentFromJson(Map<String, dynamic> json) =>
_$PortionCommentImpl( _PortionComment(
portionId: (json['id'] as num).toInt(), portionId: (json['id'] as num).toInt(),
comment: json['comment'] as String, comment: json['comment'] as String,
); );
Map<String, dynamic> _$$PortionCommentImplToJson( Map<String, dynamic> _$PortionCommentToJson(_PortionComment instance) =>
_$PortionCommentImpl instance) =>
<String, dynamic>{ <String, dynamic>{
'id': instance.portionId, 'id': instance.portionId,
'comment': instance.comment, 'comment': instance.comment,

View File

@@ -21,7 +21,7 @@ enum PortionState {
} }
@freezed @freezed
class DiaryDayWrapperModel with _$DiaryDayWrapperModel { abstract class DiaryDayWrapperModel with _$DiaryDayWrapperModel {
const factory DiaryDayWrapperModel({ const factory DiaryDayWrapperModel({
@JsonKey( @JsonKey(
name: "diary", name: "diary",
@@ -33,7 +33,7 @@ class DiaryDayWrapperModel with _$DiaryDayWrapperModel {
} }
@freezed @freezed
class DiaryDayModel with _$DiaryDayModel { abstract class DiaryDayModel with _$DiaryDayModel {
const factory DiaryDayModel({ const factory DiaryDayModel({
@JsonKey(name: "id") required int id, @JsonKey(name: "id") required int id,
@JsonKey(name: "date") required String date, @JsonKey(name: "date") required String date,
@@ -50,7 +50,7 @@ class DiaryDayModel with _$DiaryDayModel {
} }
@freezed @freezed
class MealModel with _$MealModel { abstract class MealModel with _$MealModel {
const factory MealModel({ const factory MealModel({
@JsonKey(name: "id") required int id, @JsonKey(name: "id") required int id,
@JsonKey(name: "time") required String time, @JsonKey(name: "time") required String time,
@@ -65,7 +65,7 @@ class MealModel with _$MealModel {
} }
@freezed @freezed
class DiaryPhotoModel with _$DiaryPhotoModel { abstract class DiaryPhotoModel with _$DiaryPhotoModel {
const factory DiaryPhotoModel({ const factory DiaryPhotoModel({
@JsonKey(name: "id") required int id, @JsonKey(name: "id") required int id,
@JsonKey(name: "original_name") required String originalName, @JsonKey(name: "original_name") required String originalName,
@@ -77,7 +77,7 @@ class DiaryPhotoModel with _$DiaryPhotoModel {
} }
@freezed @freezed
class PortionModel with _$PortionModel { abstract class PortionModel with _$PortionModel {
const factory PortionModel({ const factory PortionModel({
@JsonKey(name: "id") required int id, @JsonKey(name: "id") required int id,
@JsonKey(name: "product_nutritional_value_id") int? productNutritionalValueId, @JsonKey(name: "product_nutritional_value_id") int? productNutritionalValueId,
@@ -92,7 +92,7 @@ class PortionModel with _$PortionModel {
} }
@freezed @freezed
class TypeOfDiaryModel with _$TypeOfDiaryModel { abstract class TypeOfDiaryModel with _$TypeOfDiaryModel {
const factory TypeOfDiaryModel({ const factory TypeOfDiaryModel({
@JsonKey(name: "has_chosen_diet") required bool hasChosenDiet, @JsonKey(name: "has_chosen_diet") required bool hasChosenDiet,
@JsonKey(name: "has_chosen_plan") required bool hasChosenPlan, @JsonKey(name: "has_chosen_plan") required bool hasChosenPlan,
@@ -103,7 +103,7 @@ class TypeOfDiaryModel with _$TypeOfDiaryModel {
} }
@freezed @freezed
class ProductInMeal with _$ProductInMeal { abstract class ProductInMeal with _$ProductInMeal {
const factory ProductInMeal({ const factory ProductInMeal({
@JsonKey(name: 'product_name') required String productName, @JsonKey(name: 'product_name') required String productName,
@JsonKey(name: 'portion') required String portion, @JsonKey(name: 'portion') required String portion,

View File

@@ -5,7 +5,7 @@ part 'diary_index_model.freezed.dart';
part 'diary_index_model.g.dart'; part 'diary_index_model.g.dart';
@freezed @freezed
class DiaryIndexModel with _$DiaryIndexModel { abstract class DiaryIndexModel with _$DiaryIndexModel {
const factory DiaryIndexModel({ const factory DiaryIndexModel({
required int id, required int id,
}) = _DiaryIndexModel; }) = _DiaryIndexModel;

View File

@@ -5,7 +5,7 @@ part 'finish_diary_day_model.freezed.dart';
part 'finish_diary_day_model.g.dart'; part 'finish_diary_day_model.g.dart';
@Freezed() @Freezed()
class FinishDiaryDayModel with _$FinishDiaryDayModel { abstract class FinishDiaryDayModel with _$FinishDiaryDayModel {
const factory FinishDiaryDayModel({required String wakeUp, required String retire, @JsonKey(includeIfNull: false) String? comment}) = _FinishDiaryDayModel; const factory FinishDiaryDayModel({required String wakeUp, required String retire, @JsonKey(includeIfNull: false) String? comment}) = _FinishDiaryDayModel;
factory FinishDiaryDayModel.fromJson(Map<String, dynamic> json) => _$FinishDiaryDayModelFromJson(json); factory FinishDiaryDayModel.fromJson(Map<String, dynamic> json) => _$FinishDiaryDayModelFromJson(json);

View File

@@ -5,7 +5,7 @@ part 'nutrition_model.freezed.dart';
part 'nutrition_model.g.dart'; part 'nutrition_model.g.dart';
@freezed @freezed
class NutritionDataModel with _$NutritionDataModel { abstract class NutritionDataModel with _$NutritionDataModel {
const factory NutritionDataModel({ const factory NutritionDataModel({
required NutritionModel dailyNutritionIntake, required NutritionModel dailyNutritionIntake,
required NutritionModel dailyNutritionRecommendation, required NutritionModel dailyNutritionRecommendation,
@@ -15,7 +15,7 @@ class NutritionDataModel with _$NutritionDataModel {
} }
@freezed @freezed
class NutritionModel with _$NutritionModel { abstract class NutritionModel with _$NutritionModel {
const factory NutritionModel({ const factory NutritionModel({
required double energy, required double energy,
required double proteins, required double proteins,

View File

@@ -4,7 +4,7 @@ part 'product_moderation_model.freezed.dart';
part 'product_moderation_model.g.dart'; part 'product_moderation_model.g.dart';
@freezed @freezed
class ProductModerationModel with _$ProductModerationModel { abstract class ProductModerationModel with _$ProductModerationModel {
const factory ProductModerationModel({ const factory ProductModerationModel({
required String name, required String name,
@JsonKey(name: 'energy_on_100gr') @JsonKey(name: 'energy_on_100gr')

View File

@@ -5,7 +5,7 @@ import 'package:freezed_annotation/freezed_annotation.dart';
part 'consultant_comments_state.freezed.dart'; part 'consultant_comments_state.freezed.dart';
@freezed @freezed
class ConsultantCommentsState with _$ConsultantCommentsState { abstract class ConsultantCommentsState with _$ConsultantCommentsState {
factory ConsultantCommentsState({ factory ConsultantCommentsState({
required ConsultantCommentModel commentsModel, required ConsultantCommentModel commentsModel,

View File

@@ -6,7 +6,7 @@ import 'package:freezed_annotation/freezed_annotation.dart';
part 'diary_state.freezed.dart'; part 'diary_state.freezed.dart';
@freezed @freezed
class DiaryState with _$DiaryState { abstract class DiaryState with _$DiaryState {
const factory DiaryState() = _DiaryState; const factory DiaryState() = _DiaryState;
const factory DiaryState.loading() = DiaryStateLoading; const factory DiaryState.loading() = DiaryStateLoading;

View File

@@ -79,12 +79,13 @@ class _ProductWidgetState extends State<ProductWidget> {
} }
if (widget.portion.portionState == PortionState.eatenDeleted) { if (widget.portion.portionState == PortionState.eatenDeleted) {
return DottedBorder( return DottedBorder(
dashPattern: const [6, 6], options: const RoundedRectDottedBorderOptions(
padding: EdgeInsets.zero, dashPattern: [6, 6],
borderPadding: EdgeInsets.zero, padding: EdgeInsets.zero,
borderType: BorderType.RRect, borderPadding: EdgeInsets.zero,
radius: const Radius.circular(20), radius: Radius.circular(20),
color: const Color(0xFF6D6F71), color: Color(0xFF6D6F71),
),
child: ListTile( child: ListTile(
onTap: () => diaryCubit.restore( onTap: () => diaryCubit.restore(
diaryId: state.diary.id, diaryId: state.diary.id,

View File

@@ -4,7 +4,7 @@ part 'diet_likes_model.freezed.dart';
part 'diet_likes_model.g.dart'; part 'diet_likes_model.g.dart';
@freezed @freezed
class DietLikesModel with _$DietLikesModel { abstract class DietLikesModel with _$DietLikesModel {
const factory DietLikesModel({ const factory DietLikesModel({
@JsonKey(name: 'total_likers') required int totalLikes, @JsonKey(name: 'total_likers') required int totalLikes,
@JsonKey(name: 'is_liked') required bool isLiked, @JsonKey(name: 'is_liked') required bool isLiked,

View File

@@ -4,7 +4,7 @@ import 'package:freezed_annotation/freezed_annotation.dart';
part 'about_diet_state.freezed.dart'; part 'about_diet_state.freezed.dart';
@freezed @freezed
class AboutDietState with _$AboutDietState { abstract class AboutDietState with _$AboutDietState {
const factory AboutDietState() = _AboutDietState; const factory AboutDietState() = _AboutDietState;
const factory AboutDietState.initial() = DietStateInitial; const factory AboutDietState.initial() = DietStateInitial;

View File

@@ -321,6 +321,7 @@ class _AboutDietScreenState extends State<AboutDietScreen> {
path: 'diet/${widget.diet.id}', path: 'diet/${widget.diet.id}',
complainedContentType: ComplainedContent.diet, complainedContentType: ComplainedContent.diet,
id: widget.diet.id, id: widget.diet.id,
diet: widget.diet,
), ),
const SizedBox(width: 16), const SizedBox(width: 16),
], ],
@@ -501,6 +502,7 @@ class _AboutDietScreenState extends State<AboutDietScreen> {
path: 'diet/${widget.diet.id}', path: 'diet/${widget.diet.id}',
complainedContentType: ComplainedContent.diet, complainedContentType: ComplainedContent.diet,
id: widget.diet.id, id: widget.diet.id,
diet: widget.diet,
), ),
const SizedBox(width: 16), const SizedBox(width: 16),
], ],
@@ -527,6 +529,7 @@ class _AboutDietScreenState extends State<AboutDietScreen> {
path: 'diet/${widget.diet.id}', path: 'diet/${widget.diet.id}',
complainedContentType: ComplainedContent.diet, complainedContentType: ComplainedContent.diet,
id: widget.diet.id, id: widget.diet.id,
diet: widget.diet,
), ),
const SizedBox(width: 16), const SizedBox(width: 16),
], ],

View File

@@ -60,11 +60,11 @@ class MoreOptions extends StatelessWidget {
? null ? null
: () { : () {
final box = context.findRenderObject() as RenderBox?; final box = context.findRenderObject() as RenderBox?;
Share.shareUri( SharePlus.instance.share(
Uri.parse( ShareParams(
'$baseUrl/ru/$path', uri: Uri.parse('$baseUrl/ru/$path',),
sharePositionOrigin: box!.localToGlobal(Offset.zero) & box.size,
), ),
sharePositionOrigin: box!.localToGlobal(Offset.zero) & box.size,
); );
}, },
child: Row( child: Row(

View File

@@ -5,7 +5,7 @@ part 'comment_model.freezed.dart';
part 'comment_model.g.dart'; part 'comment_model.g.dart';
@freezed @freezed
class CommentModel with _$CommentModel { abstract class CommentModel with _$CommentModel {
const factory CommentModel({ const factory CommentModel({
@JsonKey(name: "data") required List<Comment> data, @JsonKey(name: "data") required List<Comment> data,
@JsonKey(name: "links") required Links links, @JsonKey(name: "links") required Links links,
@@ -16,7 +16,7 @@ class CommentModel with _$CommentModel {
} }
@freezed @freezed
class Comment with _$Comment { abstract class Comment with _$Comment {
const factory Comment({ const factory Comment({
@JsonKey(name: "id") required int id, @JsonKey(name: "id") required int id,
@JsonKey(name: "author_name") required String authorName, @JsonKey(name: "author_name") required String authorName,

View File

@@ -6,7 +6,7 @@ part 'diets_pagination_model.freezed.dart';
part 'diets_pagination_model.g.dart'; part 'diets_pagination_model.g.dart';
@freezed @freezed
class DietsPagination with _$DietsPagination { abstract class DietsPagination with _$DietsPagination {
const factory DietsPagination({ const factory DietsPagination({
@JsonKey(name: "data") required List<Diet> data, @JsonKey(name: "data") required List<Diet> data,
@JsonKey(name: "links") required Links links, @JsonKey(name: "links") required Links links,
@@ -17,7 +17,7 @@ class DietsPagination with _$DietsPagination {
} }
@freezed @freezed
class Diet with _$Diet { abstract class Diet with _$Diet {
const factory Diet({ const factory Diet({
@JsonKey(name: "id") required int id, @JsonKey(name: "id") required int id,
@JsonKey(name: "name") required String name, @JsonKey(name: "name") required String name,
@@ -42,7 +42,7 @@ class Diet with _$Diet {
enum DietState { enum DietState {
@JsonKey(name: 'active') @JsonKey(name: 'active')
active, active,
@JsonKey(name: 'draft') @JsonKey(name: 'drafted')
draft, draft,
@JsonKey(name: 'personal') @JsonKey(name: 'personal')
personal; personal;
@@ -53,7 +53,7 @@ enum DietState {
case DietState.active: case DietState.active:
return 'active'; return 'active';
case DietState.draft: case DietState.draft:
return 'draft'; return 'drafted';
case DietState.personal: case DietState.personal:
return 'personal'; return 'personal';
} }
@@ -61,7 +61,7 @@ enum DietState {
} }
@freezed @freezed
class CreatedDiet with _$CreatedDiet { abstract class CreatedDiet with _$CreatedDiet {
const factory CreatedDiet({ const factory CreatedDiet({
@JsonKey(name: "id") required int id, @JsonKey(name: "id") required int id,
}) = _CreatedDiet; }) = _CreatedDiet;
@@ -78,7 +78,7 @@ int parseDuration(dynamic duration) {
} }
@freezed @freezed
class Author with _$Author { abstract class Author with _$Author {
const factory Author({ const factory Author({
@JsonKey(name: "author_slug") required String authorSlug, @JsonKey(name: "author_slug") required String authorSlug,
@JsonKey(name: "author_name") required String authorName, @JsonKey(name: "author_name") required String authorName,
@@ -92,7 +92,7 @@ class Author with _$Author {
} }
@freezed @freezed
class DailySchedule with _$DailySchedule { abstract class DailySchedule with _$DailySchedule {
const factory DailySchedule({ const factory DailySchedule({
@JsonKey(name: "name") required String name, @JsonKey(name: "name") required String name,
@JsonKey(name: "portion") required Portion portion, @JsonKey(name: "portion") required Portion portion,
@@ -141,7 +141,7 @@ enum Portion {
} }
@freezed @freezed
class DietType with _$DietType { abstract class DietType with _$DietType {
const DietType._(); const DietType._();
const factory DietType({ const factory DietType({
@JsonKey(name: "light") bool? light, @JsonKey(name: "light") bool? light,
@@ -170,7 +170,7 @@ class EnumValues<T> {
} }
@freezed @freezed
class DailyNutrition with _$DailyNutrition { abstract class DailyNutrition with _$DailyNutrition {
const factory DailyNutrition({ const factory DailyNutrition({
@JsonKey(name: 'energy') required double energy, @JsonKey(name: 'energy') required double energy,
@JsonKey(name: 'proteins') required double proteins, @JsonKey(name: 'proteins') required double proteins,

View File

@@ -5,7 +5,7 @@ part 'feed_blog_post_model.freezed.dart';
part 'feed_blog_post_model.g.dart'; part 'feed_blog_post_model.g.dart';
@freezed @freezed
class FeedBlogPostModel with _$FeedBlogPostModel { abstract class FeedBlogPostModel with _$FeedBlogPostModel {
const factory FeedBlogPostModel({ const factory FeedBlogPostModel({
required int id, required int id,
required String state, required String state,

View File

@@ -7,7 +7,7 @@ part 'feed_blog_post_settings_model.freezed.dart';
part 'feed_blog_post_settings_model.g.dart'; part 'feed_blog_post_settings_model.g.dart';
@freezed @freezed
class FeedBlogPostSettingsModel with _$FeedBlogPostSettingsModel { abstract class FeedBlogPostSettingsModel with _$FeedBlogPostSettingsModel {
const factory FeedBlogPostSettingsModel({ const factory FeedBlogPostSettingsModel({
@JsonKey(name: 'data') required List<FeedBlogPostModel> feedBlogPostList, @JsonKey(name: 'data') required List<FeedBlogPostModel> feedBlogPostList,
required Meta meta, required Meta meta,

View File

@@ -6,7 +6,7 @@ part 'feed_consultant_model.freezed.dart';
part 'feed_consultant_model.g.dart'; part 'feed_consultant_model.g.dart';
@freezed @freezed
class FeedConsultantPaginationModel with _$FeedConsultantPaginationModel { abstract class FeedConsultantPaginationModel with _$FeedConsultantPaginationModel {
const factory FeedConsultantPaginationModel({ const factory FeedConsultantPaginationModel({
required List<FeedConsultantModel> data, required List<FeedConsultantModel> data,
required Links links, required Links links,
@@ -17,7 +17,7 @@ class FeedConsultantPaginationModel with _$FeedConsultantPaginationModel {
} }
@freezed @freezed
class FeedConsultantModel with _$FeedConsultantModel { abstract class FeedConsultantModel with _$FeedConsultantModel {
const factory FeedConsultantModel({ const factory FeedConsultantModel({
required String slug, required String slug,
required String name, required String name,

View File

@@ -8,7 +8,7 @@ part 'plan_pagination_model.freezed.dart';
part 'plan_pagination_model.g.dart'; part 'plan_pagination_model.g.dart';
@freezed @freezed
class PlanPaginationModel with _$PlanPaginationModel { abstract class PlanPaginationModel with _$PlanPaginationModel {
const factory PlanPaginationModel({ const factory PlanPaginationModel({
@JsonKey(name: "data") required List<PlanModel> data, @JsonKey(name: "data") required List<PlanModel> data,
@JsonKey(name: "links") required Links links, @JsonKey(name: "links") required Links links,
@@ -19,7 +19,7 @@ class PlanPaginationModel with _$PlanPaginationModel {
} }
@freezed @freezed
class PlanModel with _$PlanModel { abstract class PlanModel with _$PlanModel {
const factory PlanModel({ const factory PlanModel({
@JsonKey(name: "id") required int id, @JsonKey(name: "id") required int id,
@JsonKey(name: "slug") required String slug, @JsonKey(name: "slug") required String slug,
@@ -61,7 +61,7 @@ PlanType planTypeFromJson(dynamic json) {
} }
@freezed @freezed
class PacketOptions with _$PacketOptions { abstract class PacketOptions with _$PacketOptions {
const factory PacketOptions({ const factory PacketOptions({
@JsonKey(name: "items", fromJson: _parseItems) required List<String> items, @JsonKey(name: "items", fromJson: _parseItems) required List<String> items,
@JsonKey(name: "price") required dynamic price, @JsonKey(name: "price") required dynamic price,
@@ -82,7 +82,7 @@ List<String> _parseItems(json) {
} }
@freezed @freezed
class PlanType with _$PlanType { abstract class PlanType with _$PlanType {
const PlanType._(); const PlanType._();
const factory PlanType({ const factory PlanType({
@JsonKey(name: "fit", fromJson: parseBool) required bool? fit, @JsonKey(name: "fit", fromJson: parseBool) required bool? fit,

View File

@@ -5,7 +5,7 @@ part 'recipes_model.freezed.dart';
part 'recipes_model.g.dart'; part 'recipes_model.g.dart';
@freezed @freezed
class Recipe with _$Recipe { abstract class Recipe with _$Recipe {
const factory Recipe({ const factory Recipe({
required int id, required int id,
required String image, required String image,
@@ -36,14 +36,14 @@ class Recipe with _$Recipe {
} }
@freezed @freezed
class Tag with _$Tag { abstract class Tag with _$Tag {
const factory Tag({required String name}) = _Tag; const factory Tag({required String name}) = _Tag;
factory Tag.fromJson(Map<String, Object?> json) => _$TagFromJson(json); factory Tag.fromJson(Map<String, Object?> json) => _$TagFromJson(json);
} }
@freezed @freezed
class Ingredient with _$Ingredient { abstract class Ingredient with _$Ingredient {
const factory Ingredient({ const factory Ingredient({
required String name, required String name,
String? unit, String? unit,
@@ -60,7 +60,7 @@ int _parseProductId(json) {
return json as int; return json as int;
} }
@freezed @freezed
class Step with _$Step { abstract class Step with _$Step {
const factory Step({required String image, @JsonKey(name: 'description_md') required String description}) = _Step; const factory Step({required String image, @JsonKey(name: 'description_md') required String description}) = _Step;
factory Step.fromJson(Map<String, Object?> json) => _$StepFromJson(json); factory Step.fromJson(Map<String, Object?> json) => _$StepFromJson(json);

View File

@@ -6,7 +6,7 @@ part 'recipes_pagination_model.freezed.dart';
part 'recipes_pagination_model.g.dart'; part 'recipes_pagination_model.g.dart';
@freezed @freezed
class RecipesPagination with _$RecipesPagination { abstract class RecipesPagination with _$RecipesPagination {
const factory RecipesPagination({ const factory RecipesPagination({
@JsonKey(name: 'data') required List<Recipe> recipesList, @JsonKey(name: 'data') required List<Recipe> recipesList,
// @JsonKey(name: "current_page") required int currentPage, // @JsonKey(name: "current_page") required int currentPage,

View File

@@ -4,7 +4,7 @@ import 'package:freezed_annotation/freezed_annotation.dart';
part 'diets_state.freezed.dart'; part 'diets_state.freezed.dart';
@freezed @freezed
class DietsState with _$DietsState { abstract class DietsState with _$DietsState {
const factory DietsState({ const factory DietsState({
required DietsFilterState filterState, required DietsFilterState filterState,
required List<Diet> dietsList, required List<Diet> dietsList,
@@ -25,7 +25,7 @@ class DietsState with _$DietsState {
} }
@freezed @freezed
class DietsFilterState with _$DietsFilterState { abstract class DietsFilterState with _$DietsFilterState {
const factory DietsFilterState({ const factory DietsFilterState({
required int sortingIndex, required int sortingIndex,
required int durationIndex, required int durationIndex,

View File

@@ -27,7 +27,7 @@ abstract class PlansState with _$PlansState {
} }
@freezed @freezed
class PlansFilterState with _$PlansFilterState { abstract class PlansFilterState with _$PlansFilterState {
const factory PlansFilterState({ const factory PlansFilterState({
required (int?, int?) priceFilter, required (int?, int?) priceFilter,
required int durationIndex, required int durationIndex,

View File

@@ -4,7 +4,7 @@ import 'package:freezed_annotation/freezed_annotation.dart';
part 'profile_state.freezed.dart'; part 'profile_state.freezed.dart';
@freezed @freezed
class ProfileState with _$ProfileState { abstract class ProfileState with _$ProfileState {
factory ProfileState({ factory ProfileState({
ProfileModel? profile, ProfileModel? profile,

View File

@@ -243,11 +243,11 @@ class _BlogPostWidgetState extends State<BlogPostWidget> {
), ),
onTap: () { onTap: () {
final box = context.findRenderObject() as RenderBox?; final box = context.findRenderObject() as RenderBox?;
Share.shareUri( SharePlus.instance.share(
Uri.parse( ShareParams(
'$baseUrl/ru/blog_post/${state.feedBlogPostList[widget.index].id}', uri: Uri.parse('$baseUrl/ru/blog_post/${state.feedBlogPostList[widget.index].id}',),
sharePositionOrigin: box!.localToGlobal(Offset.zero) & box.size,
), ),
sharePositionOrigin: box!.localToGlobal(Offset.zero) & box.size,
); );
}, },
), ),

View File

@@ -93,6 +93,7 @@ class _DietsWidgetState extends State<DietsWidget> {
path: 'diet/${widget.diet.id}', path: 'diet/${widget.diet.id}',
id: widget.diet.id, id: widget.diet.id,
complainedContentType: ComplainedContent.diet, complainedContentType: ComplainedContent.diet,
diet: widget.diet,
), ),
), ),
), ),
@@ -185,11 +186,11 @@ class _DietsWidgetState extends State<DietsWidget> {
svgIcon: SvgPicture.asset('assets/icons/repost.svg'), svgIcon: SvgPicture.asset('assets/icons/repost.svg'),
onTap: () async { onTap: () async {
final box = context.findRenderObject() as RenderBox?; final box = context.findRenderObject() as RenderBox?;
final result = await Share.shareUri( final result = await SharePlus.instance.share(
Uri.parse( ShareParams(
'$baseUrl/ru/diet/${widget.diet.id}', uri: Uri.parse('$baseUrl/ru/diet/${widget.diet.id}'),
sharePositionOrigin: box!.localToGlobal(Offset.zero) & box.size,
), ),
sharePositionOrigin: box!.localToGlobal(Offset.zero) & box.size,
); );
switch (result.status) { switch (result.status) {
case ShareResultStatus.success: case ShareResultStatus.success:

View File

@@ -257,11 +257,11 @@ class _PlanWidgetState extends State<PlanWidget> {
svgIcon: SvgPicture.asset('assets/icons/repost.svg'), svgIcon: SvgPicture.asset('assets/icons/repost.svg'),
onTap: () async { onTap: () async {
final box = context.findRenderObject() as RenderBox?; final box = context.findRenderObject() as RenderBox?;
final result = await Share.shareUri( final result = await SharePlus.instance.share(
Uri.parse( ShareParams(
'$baseUrl/ru/diet/${widget.plan.id}', uri: Uri.parse('$baseUrl/ru/diet/${widget.plan.id}'),
sharePositionOrigin: box!.localToGlobal(Offset.zero) & box.size,
), ),
sharePositionOrigin: box!.localToGlobal(Offset.zero) & box.size,
); );
switch (result.status) { switch (result.status) {
case ShareResultStatus.success: case ShareResultStatus.success:

View File

@@ -226,11 +226,11 @@ class _RecipesWidgetState extends State<RecipesWidget> {
), ),
onTap: () { onTap: () {
final box = context.findRenderObject() as RenderBox?; final box = context.findRenderObject() as RenderBox?;
Share.shareUri( SharePlus.instance.share(
Uri.parse( ShareParams(
'$baseUrl/ru/blog_post/${widget.recipe.id}', uri: Uri.parse('$baseUrl/ru/blog_post/${widget.recipe.id}'),
sharePositionOrigin: box!.localToGlobal(Offset.zero) & box.size,
), ),
sharePositionOrigin: box!.localToGlobal(Offset.zero) & box.size,
); );
}, },
), ),

View File

@@ -4,7 +4,7 @@ part 'glossary_model.freezed.dart';
part 'glossary_model.g.dart'; part 'glossary_model.g.dart';
@freezed @freezed
class GlossaryPaginationModel with _$GlossaryPaginationModel { abstract class GlossaryPaginationModel with _$GlossaryPaginationModel {
const factory GlossaryPaginationModel({ const factory GlossaryPaginationModel({
@JsonKey(name: 'data') required List<GlossaryModel> glossariesList, @JsonKey(name: 'data') required List<GlossaryModel> glossariesList,
}) = _GlossaryPaginationModel; }) = _GlossaryPaginationModel;
@@ -13,7 +13,7 @@ class GlossaryPaginationModel with _$GlossaryPaginationModel {
} }
@freezed @freezed
class GlossaryModerationModel with _$GlossaryModerationModel { abstract class GlossaryModerationModel with _$GlossaryModerationModel {
const factory GlossaryModerationModel({ const factory GlossaryModerationModel({
@JsonKey(name: 'product_nutritional_value') required GlossaryModel glossary, @JsonKey(name: 'product_nutritional_value') required GlossaryModel glossary,
}) = _GlossaryModerationModel; }) = _GlossaryModerationModel;
@@ -22,7 +22,7 @@ class GlossaryModerationModel with _$GlossaryModerationModel {
} }
@freezed @freezed
class GlossaryModel with _$GlossaryModel { abstract class GlossaryModel with _$GlossaryModel {
const factory GlossaryModel({ const factory GlossaryModel({
required int id, required int id,
required String name, required String name,

View File

@@ -5,7 +5,7 @@ import 'package:freezed_annotation/freezed_annotation.dart';
part 'my_diets_state.freezed.dart'; part 'my_diets_state.freezed.dart';
@freezed @freezed
class MyDietsState with _$MyDietsState { abstract class MyDietsState with _$MyDietsState {
factory MyDietsState({ factory MyDietsState({
@Default([]) List<Diet> activeDiets, @Default([]) List<Diet> activeDiets,
@Default([]) List<Diet> draftDiets, @Default([]) List<Diet> draftDiets,

View File

@@ -1,4 +1,5 @@
import 'package:cached_network_image/cached_network_image.dart'; import 'package:cached_network_image/cached_network_image.dart';
import 'package:eatvio_app/core/app_router.dart';
import 'package:eatvio_app/core/const.dart'; import 'package:eatvio_app/core/const.dart';
import 'package:eatvio_app/core/theme/custom_text_style.dart'; import 'package:eatvio_app/core/theme/custom_text_style.dart';
import 'package:eatvio_app/core/theme/theme_helper.dart'; import 'package:eatvio_app/core/theme/theme_helper.dart';
@@ -7,6 +8,7 @@ import 'package:eatvio_app/core/utils/toasts.dart';
import 'package:eatvio_app/core/widgets/bottom_sheet_with_blur.dart'; import 'package:eatvio_app/core/widgets/bottom_sheet_with_blur.dart';
import 'package:eatvio_app/core/widgets/custom_outlined_button.dart'; import 'package:eatvio_app/core/widgets/custom_outlined_button.dart';
import 'package:eatvio_app/core/widgets/info_row.dart'; import 'package:eatvio_app/core/widgets/info_row.dart';
import 'package:eatvio_app/core/widgets/show_error_dialog.dart';
import 'package:eatvio_app/core/widgets/success_published_diet_bottom_sheet.dart'; import 'package:eatvio_app/core/widgets/success_published_diet_bottom_sheet.dart';
import 'package:eatvio_app/features/create_diet/presentation/create_diet_screen.dart'; import 'package:eatvio_app/features/create_diet/presentation/create_diet_screen.dart';
import 'package:eatvio_app/features/feed/models/diets_pagination_model.dart'; import 'package:eatvio_app/features/feed/models/diets_pagination_model.dart';
@@ -148,11 +150,11 @@ class _MyDietWidgetState extends State<MyDietWidget> {
CustomOutlinedButton( CustomOutlinedButton(
onPressed: () async { onPressed: () async {
final box = context.findRenderObject() as RenderBox?; final box = context.findRenderObject() as RenderBox?;
await Share.shareUri( await SharePlus.instance.share(
Uri.parse( ShareParams(
'$baseUrl/ru/diet/${widget.diet.id}', uri: Uri.parse('$baseUrl/ru/diet/${widget.diet.id}'),
sharePositionOrigin: box!.localToGlobal(Offset.zero) & box.size,
), ),
sharePositionOrigin: box!.localToGlobal(Offset.zero) & box.size,
); );
}, },
height: 52, height: 52,
@@ -194,7 +196,8 @@ class _MyDietWidgetState extends State<MyDietWidget> {
showErrorToast('Произошла ошибка. Попробуйте ещё раз через некоторое время'); showErrorToast('Произошла ошибка. Попробуйте ещё раз через некоторое время');
} }
} else { } else {
GoRouter.of(context).pushNamed(CreateDietScreen.name, extra: widget.diet); await showErrorDialog(context, title: 'Предупреждение', description: 'Вы можете создать новую диету на основе существующей.');
AppRouter.navigatorKey.currentContext?.pushNamed(CreateDietScreen.name, extra: widget.diet);
} }
}, },
text: switch (state.selectedStateIndex) { text: switch (state.selectedStateIndex) {

View File

@@ -4,7 +4,7 @@ part 'card_model.freezed.dart';
part 'card_model.g.dart'; part 'card_model.g.dart';
@freezed @freezed
class CardModel with _$CardModel { abstract class CardModel with _$CardModel {
factory CardModel({ factory CardModel({
required int id, required int id,
@JsonKey(name: 'bank_pan') required String cardNumber, @JsonKey(name: 'bank_pan') required String cardNumber,

View File

@@ -4,7 +4,7 @@ part 'payment_url_model.freezed.dart';
part 'payment_url_model.g.dart'; part 'payment_url_model.g.dart';
@freezed @freezed
class PaymentUrlModel with _$PaymentUrlModel { abstract class PaymentUrlModel with _$PaymentUrlModel {
factory PaymentUrlModel({ factory PaymentUrlModel({
required String paymentUrl, required String paymentUrl,

View File

@@ -5,7 +5,7 @@ import 'package:freezed_annotation/freezed_annotation.dart';
part 'user_cards_state.freezed.dart'; part 'user_cards_state.freezed.dart';
@freezed @freezed
class UserCardsState with _$UserCardsState { abstract class UserCardsState with _$UserCardsState {
factory UserCardsState({ factory UserCardsState({
@Default([]) List<CardModel> cards, @Default([]) List<CardModel> cards,

View File

@@ -5,7 +5,7 @@ import 'package:freezed_annotation/freezed_annotation.dart';
part 'my_plans_state.freezed.dart'; part 'my_plans_state.freezed.dart';
@freezed @freezed
class MyPlansState with _$MyPlansState { abstract class MyPlansState with _$MyPlansState {
factory MyPlansState({ factory MyPlansState({
@Default([]) List<PlanModel> activePlans, @Default([]) List<PlanModel> activePlans,
@Default([]) List<PlanModel> draftPlans, @Default([]) List<PlanModel> draftPlans,

View File

@@ -138,11 +138,11 @@ class _MyPlanWidgetState extends State<MyPlanWidget> {
CustomOutlinedButton( CustomOutlinedButton(
onPressed: () async { onPressed: () async {
final box = context.findRenderObject() as RenderBox?; final box = context.findRenderObject() as RenderBox?;
await Share.shareUri( await SharePlus.instance.share(
Uri.parse( ShareParams(
'$baseUrl/ru/plan/${widget.plan.id}', uri: Uri.parse('$baseUrl/ru/plan/${widget.plan.id}'),
sharePositionOrigin: box!.localToGlobal(Offset.zero) & box.size,
), ),
sharePositionOrigin: box!.localToGlobal(Offset.zero) & box.size,
); );
}, },
height: 52, height: 52,

View File

@@ -4,7 +4,7 @@ part 'notification_model.freezed.dart';
part 'notification_model.g.dart'; part 'notification_model.g.dart';
@freezed @freezed
class NotificationModel with _$NotificationModel { abstract class NotificationModel with _$NotificationModel {
factory NotificationModel({ factory NotificationModel({
required NotificationType type required NotificationType type

View File

@@ -4,7 +4,7 @@ import 'package:freezed_annotation/freezed_annotation.dart';
part 'order_info_state.freezed.dart'; part 'order_info_state.freezed.dart';
@freezed @freezed
class OrderInfoState with _$OrderInfoState { abstract class OrderInfoState with _$OrderInfoState {
factory OrderInfoState({ factory OrderInfoState({
@Default(true) bool isLoading, @Default(true) bool isLoading,

View File

@@ -6,7 +6,7 @@ part 'chosen_plan_model.freezed.dart';
part 'chosen_plan_model.g.dart'; part 'chosen_plan_model.g.dart';
@freezed @freezed
class ChosenPlanModel with _$ChosenPlanModel { abstract class ChosenPlanModel with _$ChosenPlanModel {
factory ChosenPlanModel({ factory ChosenPlanModel({
@JsonKey() required int id, @JsonKey() required int id,

View File

@@ -6,7 +6,7 @@ import 'package:freezed_annotation/freezed_annotation.dart';
part 'about_plan_state.freezed.dart'; part 'about_plan_state.freezed.dart';
@freezed @freezed
class AboutPlanState with _$AboutPlanState { abstract class AboutPlanState with _$AboutPlanState {
const factory AboutPlanState({ const factory AboutPlanState({
required bool isLoading, required bool isLoading,

View File

@@ -5,7 +5,7 @@ part 'badge_model.freezed.dart';
part 'badge_model.g.dart'; part 'badge_model.g.dart';
@freezed @freezed
class BadgeModel with _$BadgeModel { abstract class BadgeModel with _$BadgeModel {
const factory BadgeModel({ const factory BadgeModel({
required int id, required int id,
required String title, required String title,

Some files were not shown because too many files have changed in this diff Show More