forked from eatvio/eatvio_app
feat(app): refactoring of sentry using, feat(become_consultant): fixed possible infinite loading, feat(push_notifications): fixed push navigation from paid plan push
This commit is contained in:
@@ -9,6 +9,7 @@ import 'package:eatvio_app/features/auth/presentation/bloc/auth_cubit/auth_state
|
||||
import 'package:eatvio_app/features/auth/repositories/auth_repository.dart';
|
||||
import 'package:eatvio_app/features/profile/repositories/profile_repository.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:eatvio_app/core/error_reporting/report_from.dart';
|
||||
import 'package:flutter_native_splash/flutter_native_splash.dart';
|
||||
|
||||
class AuthCubit extends Cubit<AuthState> {
|
||||
@@ -26,7 +27,8 @@ class AuthCubit extends Cubit<AuthState> {
|
||||
emit(AuthState.loaded(token: token));
|
||||
await TokenStorage.saveTokenInStorage(token);
|
||||
return true;
|
||||
} catch (e) {
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
log(e.toString());
|
||||
showErrorToast('Неверный адрес электронной почты или пароль');
|
||||
emit(AuthState.error(errorMessage: '$e'));
|
||||
@@ -37,22 +39,30 @@ class AuthCubit extends Cubit<AuthState> {
|
||||
Future<void> initializeUser() async {
|
||||
try {
|
||||
await registerAnonymousPushToken();
|
||||
FlutterNativeSplash.remove();
|
||||
} catch (e) {
|
||||
log('Error in initializeUser: $e');
|
||||
FlutterNativeSplash.remove();
|
||||
FlutterNativeSplash.remove();
|
||||
} catch (e, st) {
|
||||
log('Error in initializeUser: $e', stackTrace: st);
|
||||
FlutterNativeSplash.remove();
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> registerAnonymousPushToken() async {
|
||||
final hasAnonymousTokenBeenSent = prefs.getBool(PrefsKeys.hasAnonymousTokenBeenSent) ?? false;
|
||||
if (!hasAnonymousTokenBeenSent) {
|
||||
await firebaseApi.registerAnonymousPushToken();
|
||||
prefs.setBool(PrefsKeys.hasAnonymousTokenBeenSent, true);
|
||||
try {
|
||||
final hasAnonymousTokenBeenSent = prefs.getBool(PrefsKeys.hasAnonymousTokenBeenSent) ?? false;
|
||||
if (!hasAnonymousTokenBeenSent) {
|
||||
await firebaseApi.registerAnonymousPushToken();
|
||||
prefs.setBool(PrefsKeys.hasAnonymousTokenBeenSent, true);
|
||||
}
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> registerPushToken() async {
|
||||
await firebaseApi.registerPushToken();
|
||||
try {
|
||||
await firebaseApi.registerPushToken();
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ import 'package:eatvio_app/features/auth/models/oauth_verification_request_respo
|
||||
import 'package:eatvio_app/features/auth/presentation/bloc/oauth_cubit/oauth_state.dart';
|
||||
import 'package:eatvio_app/features/auth/repositories/auth_repository.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:eatvio_app/core/error_reporting/report_from.dart';
|
||||
|
||||
class OAuthCubit extends Cubit<OAuthState> with RegistrationDateCacheMixin {
|
||||
final AuthRepository authRepository;
|
||||
@@ -29,7 +30,8 @@ class OAuthCubit extends Cubit<OAuthState> with RegistrationDateCacheMixin {
|
||||
log('OAuthCubit: Got token model: ${tokenModel.token}');
|
||||
TokenStorage.saveTokenInStorage(tokenModel.token);
|
||||
emit(OAuthState.loaded(token: tokenModel.token));
|
||||
} on DioException catch (e) {
|
||||
} on DioException catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
log('OAuthCubit: Error occurred: $e');
|
||||
// Проверяем, является ли ошибка ошибкой валидации email/phone
|
||||
final errors = e.response?.data['errors'] as Map<String, dynamic>?;
|
||||
@@ -62,7 +64,8 @@ class OAuthCubit extends Cubit<OAuthState> with RegistrationDateCacheMixin {
|
||||
} else {
|
||||
emit(OAuthState.error(errorMessage: e.toString()));
|
||||
}
|
||||
} catch (e) {
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
log('OAuthCubit: Error occurred: $e');
|
||||
emit(OAuthState.error(errorMessage: e.toString()));
|
||||
}
|
||||
@@ -103,7 +106,8 @@ class OAuthCubit extends Cubit<OAuthState> with RegistrationDateCacheMixin {
|
||||
TokenStorage.saveTokenInStorage(token);
|
||||
cacheRegistrationDate(DateTime.now());
|
||||
emit(OAuthState.loaded(token: token));
|
||||
} on DioException catch (e) {
|
||||
} on DioException catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
emit(OAuthState.error(errorMessage: e.toString()));
|
||||
final errors = e.response?.data['errors'] as Map<String, dynamic>?;
|
||||
final emailErrors = errors?['email'] as List<dynamic>?;
|
||||
@@ -153,7 +157,8 @@ class OAuthCubit extends Cubit<OAuthState> with RegistrationDateCacheMixin {
|
||||
// Сбрасываем состояние после успешного запроса кода
|
||||
emit(const OAuthState());
|
||||
return response;
|
||||
} catch (e) {
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
log('OAuthCubit: Error requesting verification code: $e');
|
||||
emit(OAuthState.error(errorMessage: e.toString()));
|
||||
return null;
|
||||
@@ -200,10 +205,10 @@ class OAuthCubit extends Cubit<OAuthState> with RegistrationDateCacheMixin {
|
||||
log('OAuthCubit: OAuth verification confirmed successfully, token received');
|
||||
TokenStorage.saveTokenInStorage(response.token);
|
||||
emit(OAuthState.loaded(token: response.token));
|
||||
} catch (e) {
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
log('OAuthCubit: Error confirming OAuth verification: $e');
|
||||
emit(OAuthState.error(errorMessage: e.toString()));
|
||||
rethrow; // Пробрасываем ошибку дальше, чтобы UI мог её обработать
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import 'package:eatvio_app/features/auth/presentation/bloc/reset_password_cubit/reset_password_state.dart';
|
||||
import 'package:eatvio_app/features/auth/repositories/reset_password_repository.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:eatvio_app/core/error_reporting/report_from.dart';
|
||||
|
||||
class ResetPasswordCubit extends Cubit<ResetPasswordState> {
|
||||
final ResetPasswordRepository resetPasswordRepository;
|
||||
@@ -15,7 +16,8 @@ class ResetPasswordCubit extends Cubit<ResetPasswordState> {
|
||||
} else {
|
||||
emit(const ResetPasswordState.codeSendError());
|
||||
}
|
||||
} catch (e) {
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
emit(const ResetPasswordState.codeSendError());
|
||||
}
|
||||
}
|
||||
@@ -28,7 +30,8 @@ class ResetPasswordCubit extends Cubit<ResetPasswordState> {
|
||||
} else {
|
||||
emit(const ResetPasswordState.resetPasswordError());
|
||||
}
|
||||
} catch (e) {
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
emit(const ResetPasswordState.resetPasswordError());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,7 +7,6 @@ import 'package:eatvio_app/features/auth/models/oauth_verification_confirm_respo
|
||||
import 'package:eatvio_app/features/auth/models/oauth_verification_request_response.dart';
|
||||
import 'package:eatvio_app/features/auth/models/token_model.dart';
|
||||
import 'package:eatvio_app/features/auth/services/auth_service.dart';
|
||||
import 'package:sentry_flutter/sentry_flutter.dart';
|
||||
|
||||
class AuthRepository {
|
||||
final AuthService authService;
|
||||
@@ -15,14 +14,10 @@ class AuthRepository {
|
||||
AuthRepository({required this.authService});
|
||||
|
||||
Future<TokenModel> getTokenByCredentials(String email, String password) async {
|
||||
try {
|
||||
return await authService.getTokenByCredentials(
|
||||
credentials: CredentialsModel(email: email, password: password),
|
||||
);
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
}
|
||||
return await authService.getTokenByCredentials(
|
||||
credentials: CredentialsModel(email: email, password: password),
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
Future<TokenModel> signInViaSocialMedia({
|
||||
@@ -31,14 +26,10 @@ class AuthRepository {
|
||||
required String refreshToken,
|
||||
required String clientId,
|
||||
}) async {
|
||||
try {
|
||||
return await authService.signInViaSocialMedia(
|
||||
body: OAuthLoginRequest(provider: provider, accessToken: accessToken, refreshToken: refreshToken, clientId: clientId),
|
||||
);
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
}
|
||||
return await authService.signInViaSocialMedia(
|
||||
body: OAuthLoginRequest(provider: provider, accessToken: accessToken, refreshToken: refreshToken, clientId: clientId),
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
Future<String> signUpViaSocialMedia({
|
||||
@@ -56,47 +47,39 @@ class AuthRepository {
|
||||
required int height,
|
||||
required String clientId,
|
||||
}) async {
|
||||
try {
|
||||
return (await authService.signUpViaSocialMedia(
|
||||
body: OAuthModel(
|
||||
provider: provider,
|
||||
accessToken: accessToken,
|
||||
id: id,
|
||||
refreshToken: refreshToken,
|
||||
firstName: firstName,
|
||||
lastName: lastName,
|
||||
email: email,
|
||||
phone: phone,
|
||||
dateOfBirth: dateOfBirth,
|
||||
gender: gender == 'М' ? 'male' : 'female',
|
||||
weight: weight,
|
||||
height: height,
|
||||
clientId: clientId,
|
||||
),
|
||||
))['token']!
|
||||
as String;
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
}
|
||||
return (await authService.signUpViaSocialMedia(
|
||||
body: OAuthModel(
|
||||
provider: provider,
|
||||
accessToken: accessToken,
|
||||
id: id,
|
||||
refreshToken: refreshToken,
|
||||
firstName: firstName,
|
||||
lastName: lastName,
|
||||
email: email,
|
||||
phone: phone,
|
||||
dateOfBirth: dateOfBirth,
|
||||
gender: gender == 'М' ? 'male' : 'female',
|
||||
weight: weight,
|
||||
height: height,
|
||||
clientId: clientId,
|
||||
),
|
||||
))['token']!
|
||||
as String;
|
||||
|
||||
}
|
||||
|
||||
Future<OAuthVerificationRequestResponse?> requestOAuthVerification({String? email, String? phone}) async {
|
||||
try {
|
||||
Map<String, dynamic>? body;
|
||||
if (email != null) {
|
||||
body = {'email': email};
|
||||
} else if (phone != null) {
|
||||
body = {'phone': phone};
|
||||
}
|
||||
if (body != null) {
|
||||
return await authService.requestOAuthVerification(body: body);
|
||||
}
|
||||
return null;
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
Map<String, dynamic>? body;
|
||||
if (email != null) {
|
||||
body = {'email': email};
|
||||
} else if (phone != null) {
|
||||
body = {'phone': phone};
|
||||
}
|
||||
if (body != null) {
|
||||
return await authService.requestOAuthVerification(body: body);
|
||||
}
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
Future<OAuthVerificationConfirmResponse> confirmOAuthVerification({
|
||||
@@ -116,33 +99,28 @@ class AuthRepository {
|
||||
required int weight,
|
||||
required int height,
|
||||
}) async {
|
||||
try {
|
||||
final request = OAuthVerificationConfirmRequest(
|
||||
provider: provider,
|
||||
accessToken: accessToken,
|
||||
refreshToken: refreshToken,
|
||||
clientId: clientId,
|
||||
id: id,
|
||||
email: email,
|
||||
phone: phone,
|
||||
code: code,
|
||||
verificationType: verificationType,
|
||||
firstName: firstName,
|
||||
lastName: lastName,
|
||||
dateOfBirth: dateOfBirth,
|
||||
gender: gender,
|
||||
weight: weight,
|
||||
height: height,
|
||||
);
|
||||
// Логируем запрос перед отправкой
|
||||
log(
|
||||
'AuthRepository: Sending OAuth verification confirm request: provider=$provider, verificationType=$verificationType, code=$code, email=$email, phone=$phone',
|
||||
);
|
||||
return await authService.confirmOAuthVerification(body: request);
|
||||
} catch (e, s) {
|
||||
log('AuthRepository: Error in confirmOAuthVerification: $e');
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
}
|
||||
final request = OAuthVerificationConfirmRequest(
|
||||
provider: provider,
|
||||
accessToken: accessToken,
|
||||
refreshToken: refreshToken,
|
||||
clientId: clientId,
|
||||
id: id,
|
||||
email: email,
|
||||
phone: phone,
|
||||
code: code,
|
||||
verificationType: verificationType,
|
||||
firstName: firstName,
|
||||
lastName: lastName,
|
||||
dateOfBirth: dateOfBirth,
|
||||
gender: gender,
|
||||
weight: weight,
|
||||
height: height,
|
||||
);
|
||||
// Логируем запрос перед отправкой
|
||||
log(
|
||||
'AuthRepository: Sending OAuth verification confirm request: provider=$provider, verificationType=$verificationType, code=$code, email=$email, phone=$phone',
|
||||
);
|
||||
return await authService.confirmOAuthVerification(body: request);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import 'package:eatvio_app/features/auth/services/reset_password_service.dart';
|
||||
import 'package:sentry_flutter/sentry_flutter.dart';
|
||||
|
||||
class ResetPasswordRepository {
|
||||
final ResetPasswordService resetPasswordService;
|
||||
@@ -9,22 +8,18 @@ class ResetPasswordRepository {
|
||||
});
|
||||
|
||||
Future<bool> sendEmailCodeForPasswordChange(String email) async {
|
||||
try {
|
||||
final response = await resetPasswordService.sendEmailCodeForPasswordChange(
|
||||
data: {
|
||||
'email': email,
|
||||
},
|
||||
);
|
||||
int statusCode = response.response.statusCode ?? 0;
|
||||
if (statusCode >= 200 && statusCode < 300) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
final response = await resetPasswordService.sendEmailCodeForPasswordChange(
|
||||
data: {
|
||||
'email': email,
|
||||
},
|
||||
);
|
||||
int statusCode = response.response.statusCode ?? 0;
|
||||
if (statusCode >= 200 && statusCode < 300) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Future<bool> confirmPasswordChange(
|
||||
@@ -33,24 +28,20 @@ class ResetPasswordRepository {
|
||||
String passwordConfirmation,
|
||||
String email,
|
||||
) async {
|
||||
try {
|
||||
final response = await resetPasswordService.confirmPasswordChange(
|
||||
data: {
|
||||
'code': code,
|
||||
'password': password,
|
||||
'password_confirmation': passwordConfirmation,
|
||||
'email': email,
|
||||
},
|
||||
);
|
||||
int statusCode = response.response.statusCode ?? 0;
|
||||
if (statusCode >= 200 && statusCode < 300) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
final response = await resetPasswordService.confirmPasswordChange(
|
||||
data: {
|
||||
'code': code,
|
||||
'password': password,
|
||||
'password_confirmation': passwordConfirmation,
|
||||
'email': email,
|
||||
},
|
||||
);
|
||||
int statusCode = response.response.statusCode ?? 0;
|
||||
if (statusCode >= 200 && statusCode < 300) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,10 +8,11 @@ import 'package:eatvio_app/features/auth/models/yandex_profile_model.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:eatvio_app/core/app_router.dart';
|
||||
import 'package:eatvio_app/core/env_config.dart';
|
||||
import 'package:eatvio_app/core/locator_service.dart';
|
||||
import 'package:eatvio_app/core/error_reporting/error_reporter.dart';
|
||||
import 'package:eatvio_app/generated/l10n.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'package:sentry_flutter/sentry_flutter.dart';
|
||||
import 'package:vk_id/vk_id.dart';
|
||||
import 'package:webview_flutter/webview_flutter.dart';
|
||||
|
||||
@@ -43,7 +44,7 @@ class SocialAuthFacade {
|
||||
}
|
||||
return await _parseVKAuthResult(redirectParams: redirectParams, controller: controller, codeVerifier: codeVerifier, clientId: clientIdStr);
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
await sl<ErrorReporter>().report(e, s, origin: 'SocialAuthFacade');
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -161,7 +162,7 @@ class SocialAuthFacade {
|
||||
);
|
||||
} catch (e, s) {
|
||||
log(e.toString());
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
await sl<ErrorReporter>().report(e, s, origin: 'SocialAuthFacade');
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@@ -209,7 +210,7 @@ class SocialAuthFacade {
|
||||
|
||||
return await _parseVKAuthResult(redirectParams: redirectParams, controller: controller, codeVerifier: codeVerifier, clientId: clientIdStr);
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
await sl<ErrorReporter>().report(e, s, origin: 'SocialAuthFacade');
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:eatvio_app/features/barcode/models/barcode_product_model.dart';
|
||||
import 'package:eatvio_app/features/barcode/services/barcode_service.dart';
|
||||
import 'package:sentry_flutter/sentry_flutter.dart';
|
||||
|
||||
class BarcodeRepository {
|
||||
final BarcodeService barcodeService;
|
||||
@@ -15,49 +14,46 @@ class BarcodeRepository {
|
||||
/// Получить информацию о продукте по штрихкоду
|
||||
/// Возвращает либо данные продукта, либо статус задачи обработки
|
||||
Future<BarcodeResult> getProductByBarcode(String barcode) async {
|
||||
try {
|
||||
final response = await dio.get('/api/gsone/barcode/$barcode');
|
||||
|
||||
if (response.statusCode == 200) {
|
||||
// Данные найдены в БД
|
||||
final product = BarcodeProductModel.fromJson(response.data as Map<String, dynamic>);
|
||||
return BarcodeResult.success(product);
|
||||
} else if (response.statusCode == 202) {
|
||||
// Запущена задача обработки
|
||||
final taskStatus = BarcodeTaskStatusModel.fromJson(response.data as Map<String, dynamic>);
|
||||
return BarcodeResult.processing(taskStatus.taskId ?? '');
|
||||
}
|
||||
|
||||
throw Exception('Unexpected status code: ${response.statusCode}');
|
||||
} on DioException catch (e, s) {
|
||||
if (e.response?.statusCode == 202) {
|
||||
// Если получен статус 202, значит запущена задача обработки
|
||||
final taskStatus = BarcodeTaskStatusModel.fromJson(e.response!.data as Map<String, dynamic>);
|
||||
return BarcodeResult.processing(taskStatus.taskId ?? '');
|
||||
}
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
final response = await dio.get<Map<String, dynamic>>(
|
||||
'/api/gsone/barcode/$barcode',
|
||||
options: Options(validateStatus: (_) => true),
|
||||
);
|
||||
|
||||
final code = response.statusCode ?? 0;
|
||||
final data = response.data;
|
||||
if (data is! Map<String, dynamic>) {
|
||||
throw DioException(
|
||||
requestOptions: response.requestOptions,
|
||||
response: response,
|
||||
message: 'Invalid barcode response',
|
||||
);
|
||||
}
|
||||
if (code == 200) {
|
||||
final product = BarcodeProductModel.fromJson(data);
|
||||
return BarcodeResult.success(product);
|
||||
}
|
||||
if (code == 202) {
|
||||
final taskStatus = BarcodeTaskStatusModel.fromJson(data);
|
||||
return BarcodeResult.processing(taskStatus.taskId ?? '');
|
||||
}
|
||||
|
||||
throw DioException(
|
||||
requestOptions: response.requestOptions,
|
||||
response: response,
|
||||
message: 'Unexpected status code: $code',
|
||||
);
|
||||
}
|
||||
|
||||
/// Получить статус задачи обработки
|
||||
Future<BarcodeTaskStatus> getTaskStatus(String taskId) async {
|
||||
try {
|
||||
final statusModel = await barcodeService.getTaskStatus(taskId: taskId);
|
||||
|
||||
if (statusModel.status == 'completed' && statusModel.data != null) {
|
||||
return BarcodeTaskStatus.completed(statusModel.data!);
|
||||
} else if (statusModel.status == 'failed') {
|
||||
return BarcodeTaskStatus.failed();
|
||||
} else {
|
||||
return BarcodeTaskStatus.processing();
|
||||
}
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
final statusModel = await barcodeService.getTaskStatus(taskId: taskId);
|
||||
|
||||
if (statusModel.status == 'completed' && statusModel.data != null) {
|
||||
return BarcodeTaskStatus.completed(statusModel.data!);
|
||||
} else if (statusModel.status == 'failed') {
|
||||
return BarcodeTaskStatus.failed();
|
||||
} else {
|
||||
return BarcodeTaskStatus.processing();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -109,4 +105,3 @@ enum BarcodeTaskStatusType {
|
||||
processing,
|
||||
failed,
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ import 'dart:developer';
|
||||
import 'package:eatvio_app/features/blog_post/presentation/cubit/blog_post_state.dart';
|
||||
import 'package:eatvio_app/features/feed/repositories/feed_repository.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:eatvio_app/core/error_reporting/report_from.dart';
|
||||
|
||||
class BlogPostCubit extends Cubit<BlogPostState> {
|
||||
final FeedRepository feedRepository;
|
||||
@@ -16,6 +17,7 @@ class BlogPostCubit extends Cubit<BlogPostState> {
|
||||
|
||||
emit(state.copyWith(blogPostModel: postModel, isLoading: false));
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
log(e.toString(), stackTrace: st);
|
||||
emit(state.copyWith(isLoading: false));
|
||||
}
|
||||
@@ -37,6 +39,7 @@ class BlogPostCubit extends Cubit<BlogPostState> {
|
||||
await feedRepository.likeBlogPost(id: current.id);
|
||||
}
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
// rollback on error
|
||||
log(e.toString(), stackTrace: st);
|
||||
emit(state.copyWith(blogPostModel: current));
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
import 'package:eatvio_app/core/cubit/base_cubit.dart';
|
||||
import 'dart:developer';
|
||||
|
||||
import 'package:eatvio_app/core/error_reporting/report_from.dart';
|
||||
import 'package:eatvio_app/features/blog_post_create/bloc/blog_post_create_cubit/blog_post_create_state.dart';
|
||||
import 'package:eatvio_app/features/blog_post_create/repositories/blog_post_repository.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:flutter_image_compress/flutter_image_compress.dart';
|
||||
|
||||
class BlogPostCreateCubit extends BaseCubit<BlogPostCreateState> {
|
||||
class BlogPostCreateCubit extends Cubit<BlogPostCreateState> {
|
||||
final BlogPostRepository blogPostRepository;
|
||||
|
||||
BlogPostCreateCubit({required this.blogPostRepository}) : super(const BlogPostCreateState());
|
||||
@@ -15,7 +18,8 @@ class BlogPostCreateCubit extends BaseCubit<BlogPostCreateState> {
|
||||
emit(const BlogPostCreateState.loaded());
|
||||
return true;
|
||||
} catch (error, stackTrace) {
|
||||
handleError(error, stackTrace);
|
||||
log('BlogPostCreateCubit: $error', stackTrace: stackTrace);
|
||||
await reportFrom(error, stackTrace, this);
|
||||
emit(BlogPostCreateState.error(errorMessage: error.toString()));
|
||||
return false;
|
||||
}
|
||||
@@ -28,7 +32,8 @@ class BlogPostCreateCubit extends BaseCubit<BlogPostCreateState> {
|
||||
emit(const BlogPostCreateState.loaded());
|
||||
return true;
|
||||
} catch (error, stackTrace) {
|
||||
handleError(error, stackTrace);
|
||||
log('BlogPostCreateCubit: $error', stackTrace: stackTrace);
|
||||
await reportFrom(error, stackTrace, this);
|
||||
emit(BlogPostCreateState.error(errorMessage: error.toString()));
|
||||
return false;
|
||||
}
|
||||
@@ -39,7 +44,8 @@ class BlogPostCreateCubit extends BaseCubit<BlogPostCreateState> {
|
||||
await blogPostRepository.deleteBlogPost(id);
|
||||
return true;
|
||||
} catch (error, stackTrace) {
|
||||
handleError(error, stackTrace);
|
||||
log('BlogPostCreateCubit: $error', stackTrace: stackTrace);
|
||||
await reportFrom(error, stackTrace, this);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import 'dart:developer';
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:eatvio_app/core/app_config.dart';
|
||||
import 'package:eatvio_app/core/locator_service.dart';
|
||||
@@ -8,7 +8,6 @@ import 'package:eatvio_app/core/image_compressing/image_compress_utility.dart';
|
||||
import 'package:eatvio_app/features/blog_post_create/services/blog_post_service.dart';
|
||||
import 'package:flutter_image_compress/flutter_image_compress.dart';
|
||||
import 'package:path_provider/path_provider.dart';
|
||||
import 'package:sentry_flutter/sentry_flutter.dart';
|
||||
|
||||
class BlogPostRepository {
|
||||
final BlogPostService blogPostService;
|
||||
@@ -23,48 +22,30 @@ class BlogPostRepository {
|
||||
String? description,
|
||||
XFile? image,
|
||||
) async {
|
||||
FormData formData = FormData.fromMap({
|
||||
final formData = FormData.fromMap({
|
||||
if (title != null && title.isNotEmpty) 'title': title,
|
||||
if (description != null && description.isNotEmpty) 'description_md': description,
|
||||
if (videoUrl != null && videoUrl.isNotEmpty) 'video_url': videoUrl,
|
||||
if (image != null) 'image': await MultipartFile.fromFile((await ImageCompressUtility.compressFile(File(image.path))).path, filename: image.name),
|
||||
});
|
||||
|
||||
try {
|
||||
return await blogPostService.createBlogPost(
|
||||
formData: formData,
|
||||
);
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
}
|
||||
return blogPostService.createBlogPost(
|
||||
formData: formData,
|
||||
);
|
||||
}
|
||||
|
||||
Future<XFile?> downloadImage(String imageUrl) async {
|
||||
try {
|
||||
// Загрузка изображения
|
||||
final response = await http.get(Uri.parse('${sl<AppConfig>().baseUrl}/storage/$imageUrl'));
|
||||
final response = await http.get(Uri.parse('${sl<AppConfig>().baseUrl}/storage/$imageUrl'));
|
||||
|
||||
if (response.statusCode == 200) {
|
||||
// Получение временной директории
|
||||
final directory = await getTemporaryDirectory();
|
||||
// Создание файла в временной директории
|
||||
final filePath = '${directory.path}/image.jpg'; // Вы можете изменить название файла
|
||||
final file = File(filePath);
|
||||
// Запись данных в файл
|
||||
await file.writeAsBytes(response.bodyBytes);
|
||||
if (response.statusCode == 200) {
|
||||
final directory = await getTemporaryDirectory();
|
||||
final filePath = '${directory.path}/image.jpg';
|
||||
final file = File(filePath);
|
||||
await file.writeAsBytes(response.bodyBytes);
|
||||
|
||||
// Возвращаем объект XFile
|
||||
return XFile(file.path);
|
||||
} else {
|
||||
log('Ошибка загрузки изображения: ${response.statusCode}');
|
||||
return null;
|
||||
}
|
||||
} catch (e, s) {
|
||||
log('Произошла ошибка: $e');
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
return null;
|
||||
return XFile(file.path);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
Future<void> updateBlogPost(
|
||||
@@ -75,9 +56,9 @@ class BlogPostRepository {
|
||||
XFile? image,
|
||||
String? oldImageUrl,
|
||||
) async {
|
||||
FormData formData = FormData.fromMap({
|
||||
final formData = FormData.fromMap({
|
||||
'title': title,
|
||||
'description_md': description,
|
||||
'description_md': description,
|
||||
'video_url': videoUrl,
|
||||
'image': image != null
|
||||
? await MultipartFile.fromFile((await ImageCompressUtility.compressFile(File(image.path))).path, filename: image.name)
|
||||
@@ -86,23 +67,13 @@ class BlogPostRepository {
|
||||
: null,
|
||||
});
|
||||
|
||||
try {
|
||||
return await blogPostService.updateBlogPost(
|
||||
id: id,
|
||||
formData: formData,
|
||||
);
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
}
|
||||
return blogPostService.updateBlogPost(
|
||||
id: id,
|
||||
formData: formData,
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> deleteBlogPost(int id) async {
|
||||
try {
|
||||
await blogPostService.deleteBlogPost(id: id);
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
}
|
||||
await blogPostService.deleteBlogPost(id: id);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:appmetrica_plugin/appmetrica_plugin.dart';
|
||||
import 'package:eatvio_app/core/app_router.dart';
|
||||
import 'package:eatvio_app/features/bottom_navigation_bar/presentation/bloc/profile_avatar_cubit/profile_avatar_state.dart';
|
||||
import 'package:eatvio_app/features/profile/repositories/profile_repository.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:eatvio_app/core/error_reporting/report_from.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:permission_handler/permission_handler.dart';
|
||||
|
||||
@@ -28,7 +31,8 @@ class ProfileAvatarCubit extends Cubit<ProfileAvatarState> {
|
||||
|
||||
return age;
|
||||
}
|
||||
} catch (e) {
|
||||
} catch (e, st) {
|
||||
unawaited(reportFrom(e, st, this));
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
@@ -51,10 +55,12 @@ class ProfileAvatarCubit extends Cubit<ProfileAvatarState> {
|
||||
]);
|
||||
AppMetrica.setUserProfileID(profile.slug);
|
||||
AppMetrica.reportUserProfile(userProfile);
|
||||
} catch (e) {
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
// Игнорируем ошибки плагинов, профиль уже загружен
|
||||
}
|
||||
} catch (e) {
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
AppRouter.navigatorKey.currentContext?.go('/auth-screen');
|
||||
emit(ProfileAvatarState.error(errorMessage: e.toString()));
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import 'package:eatvio_app/features/calendar/presentation/bloc/calendar_state.dart';
|
||||
import 'package:eatvio_app/features/calendar/repositories/calendar_repository.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:eatvio_app/core/error_reporting/report_from.dart';
|
||||
|
||||
class CalendarCubit extends Cubit<CalendarState> {
|
||||
final CalendarRepository calendarRepository;
|
||||
@@ -12,7 +13,8 @@ class CalendarCubit extends Cubit<CalendarState> {
|
||||
try {
|
||||
final calendarList = await calendarRepository.getCalendar();
|
||||
emit(CalendarState.loaded(calendarList: calendarList));
|
||||
} catch (e) {
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
emit(CalendarState.error(errorMessage: e.toString()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import 'package:eatvio_app/features/calendar/models/calendar_model.dart';
|
||||
import 'package:eatvio_app/features/calendar/services/calendar_service.dart';
|
||||
import 'package:sentry_flutter/sentry_flutter.dart';
|
||||
|
||||
class CalendarRepository {
|
||||
final CalendarService calendarService;
|
||||
@@ -8,11 +7,7 @@ class CalendarRepository {
|
||||
CalendarRepository({required this.calendarService});
|
||||
|
||||
Future<List<CalendarModel>> getCalendar() async {
|
||||
try {
|
||||
return await calendarService.getCalendar();
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
}
|
||||
return await calendarService.getCalendar();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import 'package:eatvio_app/features/cancel_plan_bottom_sheet/cubit/cancel_plan_s
|
||||
import 'package:eatvio_app/features/cancel_plan_bottom_sheet/models/cancelation_model.dart';
|
||||
import 'package:eatvio_app/features/cancel_plan_bottom_sheet/repository/cancel_plan_repository.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:eatvio_app/core/error_reporting/report_from.dart';
|
||||
|
||||
class CancelPlanCubit extends Cubit<CancelPlanState> {
|
||||
final CancelPlanRepository cancelPlanRepository;
|
||||
@@ -18,6 +19,7 @@ class CancelPlanCubit extends Cubit<CancelPlanState> {
|
||||
await cancelPlanRepository.cancelChosenPlan(id: id, body: body);
|
||||
return true;
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
log(e.toString(), stackTrace: st);
|
||||
}
|
||||
return false;
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import 'package:eatvio_app/features/cancel_plan_bottom_sheet/models/cancelation_model.dart';
|
||||
import 'package:eatvio_app/features/cancel_plan_bottom_sheet/service/cancel_plan_service.dart';
|
||||
import 'package:sentry_flutter/sentry_flutter.dart';
|
||||
|
||||
class CancelPlanRepository {
|
||||
final CancelPlanService cancelService;
|
||||
@@ -9,11 +8,7 @@ class CancelPlanRepository {
|
||||
required int id,
|
||||
CancelationModel? body
|
||||
}) async {
|
||||
try {
|
||||
await cancelService.cancelChosenPlan(id: id, body: body);
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
}
|
||||
await cancelService.cancelChosenPlan(id: id, body: body);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ import 'package:eatvio_app/features/my_finance/models/card_model.dart';
|
||||
import 'package:eatvio_app/features/my_finance/repositories/cards_repository.dart';
|
||||
import 'package:eatvio_app/features/plans/models/chosen_plan_model.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:eatvio_app/core/error_reporting/report_from.dart';
|
||||
import 'package:uuid/uuid.dart';
|
||||
|
||||
class ChatRoomCubit extends Cubit<ChatRoomState> {
|
||||
@@ -64,7 +65,8 @@ class ChatRoomCubit extends Cubit<ChatRoomState> {
|
||||
);
|
||||
|
||||
currentPage++;
|
||||
} catch (e) {
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
emit(const ChatRoomState.error(errorMessage: 'Ошибка получеия данных'));
|
||||
}
|
||||
}
|
||||
@@ -75,6 +77,7 @@ class ChatRoomCubit extends Cubit<ChatRoomState> {
|
||||
final cards = await cardsRepository.getCards();
|
||||
_setCard(cards: cards);
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
log(e.toString(), stackTrace: st);
|
||||
}
|
||||
}
|
||||
@@ -111,7 +114,8 @@ class ChatRoomCubit extends Cubit<ChatRoomState> {
|
||||
if (chosenPlan?.consultantId == chatRoom.users.sender.id) {
|
||||
await checkCards();
|
||||
}
|
||||
} catch (e) {
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
log(e.toString());
|
||||
typingSubscription?.cancel();
|
||||
messagesSubscription?.cancel();
|
||||
@@ -121,13 +125,17 @@ class ChatRoomCubit extends Cubit<ChatRoomState> {
|
||||
}
|
||||
|
||||
Future<void> updateChosenPlanState() async {
|
||||
final currentState = state;
|
||||
if (currentState is ChatRoomStateLoaded) {
|
||||
final chosenPlanId = currentState.chatRoom.chosenPlanId;
|
||||
if (chosenPlanId != null) {
|
||||
final chosenPlan = await chatRepository.getChosenPlan(id: chosenPlanId);
|
||||
emit(currentState.copyWith.chatRoom(chosenPlan: chosenPlan));
|
||||
try {
|
||||
final currentState = state;
|
||||
if (currentState is ChatRoomStateLoaded) {
|
||||
final chosenPlanId = currentState.chatRoom.chosenPlanId;
|
||||
if (chosenPlanId != null) {
|
||||
final chosenPlan = await chatRepository.getChosenPlan(id: chosenPlanId);
|
||||
emit(currentState.copyWith.chatRoom(chosenPlan: chosenPlan));
|
||||
}
|
||||
}
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -142,6 +150,7 @@ class ChatRoomCubit extends Cubit<ChatRoomState> {
|
||||
emit((state as ChatRoomStateLoaded).copyWith.chatRoom(chosenPlan: chosenPlan));
|
||||
return true;
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
log(e.toString(), stackTrace: st);
|
||||
return false;
|
||||
}
|
||||
@@ -151,7 +160,8 @@ class ChatRoomCubit extends Cubit<ChatRoomState> {
|
||||
try {
|
||||
await chatRepository.cancelChosenPlan(id: planId);
|
||||
emit((state as ChatRoomStateLoaded).copyWith.chatRoom(chosenPlan: null));
|
||||
} catch (e) {
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
emit(const ChatRoomState.error(errorMessage: 'Ошибка получеия данных'));
|
||||
}
|
||||
}
|
||||
@@ -238,7 +248,8 @@ class ChatRoomCubit extends Cubit<ChatRoomState> {
|
||||
}).toList(),
|
||||
),
|
||||
);
|
||||
} catch (e) {
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
emit(
|
||||
(state as ChatRoomStateLoaded).copyWith(
|
||||
chatMessages: (state as ChatRoomStateLoaded).chatMessages.map((elem) {
|
||||
@@ -253,6 +264,7 @@ class ChatRoomCubit extends Cubit<ChatRoomState> {
|
||||
sl<ChatsCubit>().getChatRooms();
|
||||
return true;
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
log(e.toString(), stackTrace: st);
|
||||
return false;
|
||||
}
|
||||
@@ -274,6 +286,7 @@ class ChatRoomCubit extends Cubit<ChatRoomState> {
|
||||
}
|
||||
return false;
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
log(e.toString(), stackTrace: st);
|
||||
return false;
|
||||
}
|
||||
@@ -286,6 +299,7 @@ class ChatRoomCubit extends Cubit<ChatRoomState> {
|
||||
final paymentModel = await chatRepository.getPaymentLink(id: planId);
|
||||
return paymentModel.paymentUrl;
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
log(e.toString(), stackTrace: st);
|
||||
return null;
|
||||
}
|
||||
@@ -300,7 +314,8 @@ class ChatRoomCubit extends Cubit<ChatRoomState> {
|
||||
body: PlanComplainModel(description: description),
|
||||
);
|
||||
return true;
|
||||
} catch (e) {
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
log(e.toString());
|
||||
return false;
|
||||
}
|
||||
@@ -312,7 +327,8 @@ class ChatRoomCubit extends Cubit<ChatRoomState> {
|
||||
if (planId == null) return false;
|
||||
await chatRepository.finishChosenPlan(id: planId);
|
||||
return true;
|
||||
} catch (e) {
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
log(e.toString());
|
||||
return false;
|
||||
}
|
||||
@@ -400,7 +416,8 @@ class ChatRoomCubit extends Cubit<ChatRoomState> {
|
||||
}).toList(),
|
||||
),
|
||||
);
|
||||
} catch (e) {
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
emit(
|
||||
(state as ChatRoomStateLoaded).copyWith(
|
||||
chatMessages: (state as ChatRoomStateLoaded).chatMessages.map((elem) {
|
||||
@@ -414,6 +431,7 @@ class ChatRoomCubit extends Cubit<ChatRoomState> {
|
||||
}
|
||||
sl<ChatsCubit>().getChatRooms();
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
log(e.toString(), stackTrace: st);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ import 'package:eatvio_app/features/chat/presentation/bloc/chats_cubit/chats_sta
|
||||
import 'package:eatvio_app/features/chat/repositories/chat_repository.dart';
|
||||
import 'package:eatvio_app/features/profile/repositories/profile_repository.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:eatvio_app/core/error_reporting/report_from.dart';
|
||||
|
||||
class ChatsCubit extends Cubit<ChatsState> {
|
||||
final ChatRepository chatRepository;
|
||||
@@ -31,10 +32,14 @@ class ChatsCubit extends Cubit<ChatsState> {
|
||||
late int lastPage;
|
||||
|
||||
Future<void> connectToWebSocket() async {
|
||||
await newIncomingMessagesSubscription?.cancel();
|
||||
newIncomingMessagesSubscription = wsManager.newMessagesStream?.listen((event) {
|
||||
_handleNewMessageViaSocket(event.data);
|
||||
});
|
||||
try {
|
||||
await newIncomingMessagesSubscription?.cancel();
|
||||
newIncomingMessagesSubscription = wsManager.newMessagesStream?.listen((event) {
|
||||
_handleNewMessageViaSocket(event.data);
|
||||
});
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> getChatRoomsWithLoading({String? query}) async {
|
||||
@@ -53,7 +58,8 @@ class ChatsCubit extends Cubit<ChatsState> {
|
||||
),
|
||||
);
|
||||
page++;
|
||||
} catch (e) {
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
emit(
|
||||
state.copyWith(errorMessage: e.toString(), state: BaseState.error),
|
||||
);
|
||||
@@ -76,6 +82,7 @@ class ChatsCubit extends Cubit<ChatsState> {
|
||||
);
|
||||
page++;
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
log(e.toString(), stackTrace: st);
|
||||
emit(
|
||||
state.copyWith(errorMessage: e.toString(), state: BaseState.error),
|
||||
@@ -99,6 +106,7 @@ class ChatsCubit extends Cubit<ChatsState> {
|
||||
);
|
||||
page++;
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
log(e.toString(), stackTrace: st);
|
||||
emit(
|
||||
state.copyWith(
|
||||
@@ -132,33 +140,37 @@ class ChatsCubit extends Cubit<ChatsState> {
|
||||
}
|
||||
|
||||
Future<void> _handleNewMessageViaSocket(dynamic data) async {
|
||||
final json = jsonDecode(data);
|
||||
final message = ChatMessageModel.fromJson(json['message']);
|
||||
try {
|
||||
final json = jsonDecode(data);
|
||||
final message = ChatMessageModel.fromJson(json['message']);
|
||||
|
||||
final currentChatRooms = [...state.chatRooms];
|
||||
final currentChatRooms = [...state.chatRooms];
|
||||
|
||||
bool wasChanged = false;
|
||||
bool willIncrementUnreadChats = false;
|
||||
final updatedChatRooms = currentChatRooms.map((chatRoom) {
|
||||
if (chatRoom.id == message.roomId) {
|
||||
wasChanged = true;
|
||||
if (chatRoom.unreadMessagesCount == 0) {
|
||||
willIncrementUnreadChats = true;
|
||||
bool wasChanged = false;
|
||||
bool willIncrementUnreadChats = false;
|
||||
final updatedChatRooms = currentChatRooms.map((chatRoom) {
|
||||
if (chatRoom.id == message.roomId) {
|
||||
wasChanged = true;
|
||||
if (chatRoom.unreadMessagesCount == 0) {
|
||||
willIncrementUnreadChats = true;
|
||||
}
|
||||
return chatRoom.copyWith(lastMessage: message, unreadMessagesCount: chatRoom.unreadMessagesCount + 1);
|
||||
}
|
||||
return chatRoom.copyWith(lastMessage: message, unreadMessagesCount: chatRoom.unreadMessagesCount + 1);
|
||||
}
|
||||
return chatRoom;
|
||||
}).toList();
|
||||
return chatRoom;
|
||||
}).toList();
|
||||
|
||||
if (!wasChanged && _query == null) {
|
||||
getChatRooms();
|
||||
} else {
|
||||
emit(
|
||||
state.copyWith(
|
||||
chatRooms: updatedChatRooms,
|
||||
chatsWithUnreadMessagesCount: willIncrementUnreadChats ? state.chatsWithUnreadMessagesCount + 1 : state.chatsWithUnreadMessagesCount,
|
||||
),
|
||||
);
|
||||
if (!wasChanged && _query == null) {
|
||||
getChatRooms();
|
||||
} else {
|
||||
emit(
|
||||
state.copyWith(
|
||||
chatRooms: updatedChatRooms,
|
||||
chatsWithUnreadMessagesCount: willIncrementUnreadChats ? state.chatsWithUnreadMessagesCount + 1 : state.chatsWithUnreadMessagesCount,
|
||||
),
|
||||
);
|
||||
}
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import 'dart:async';
|
||||
import 'dart:developer';
|
||||
import 'dart:io';
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:eatvio_app/core/token_storage.dart';
|
||||
@@ -12,7 +11,6 @@ import 'package:eatvio_app/features/chat/models/plan_complain_model.dart';
|
||||
import 'package:eatvio_app/features/chat/services/chat_service.dart';
|
||||
import 'package:eatvio_app/features/plans/models/chosen_plan_model.dart';
|
||||
import 'package:http_parser/http_parser.dart';
|
||||
import 'package:sentry_flutter/sentry_flutter.dart';
|
||||
|
||||
class ChatRepository {
|
||||
final ChatService chatService;
|
||||
@@ -34,160 +32,104 @@ class ChatRepository {
|
||||
String? data,
|
||||
List<File>? files,
|
||||
}) async {
|
||||
try {
|
||||
final multipartFiles = <MultipartFile>[];
|
||||
final multipartFiles = <MultipartFile>[];
|
||||
|
||||
if (files != null) {
|
||||
for (final file in files) {
|
||||
final fileBytes = await file.readAsBytes();
|
||||
final multipartFile = MultipartFile.fromBytes(
|
||||
fileBytes,
|
||||
filename: file.path.split('/').last,
|
||||
contentType: MediaType('application', 'octet-stream'),
|
||||
);
|
||||
multipartFiles.add(multipartFile);
|
||||
}
|
||||
if (files != null) {
|
||||
for (final file in files) {
|
||||
final fileBytes = await file.readAsBytes();
|
||||
final multipartFile = MultipartFile.fromBytes(
|
||||
fileBytes,
|
||||
filename: file.path.split('/').last,
|
||||
contentType: MediaType('application', 'octet-stream'),
|
||||
);
|
||||
multipartFiles.add(multipartFile);
|
||||
}
|
||||
|
||||
// Если data пустая строка или null, не передаем её вообще
|
||||
// Сервер требует либо непустую строку, либо отсутствие поля
|
||||
final dataToSend = (data == null || data.trim().isEmpty) ? null : data;
|
||||
|
||||
return await chatService.sendMessage(
|
||||
slug: slug,
|
||||
data: dataToSend,
|
||||
mediaData: multipartFiles.isEmpty ? null : multipartFiles,
|
||||
socketId: (await SocketIdStorage.getSocketIdFromStorage())!,
|
||||
);
|
||||
} catch (e, st) {
|
||||
log(e.toString(), stackTrace: st);
|
||||
await Sentry.captureException(e, stackTrace: st);
|
||||
rethrow;
|
||||
}
|
||||
|
||||
// Если data пустая строка или null, не передаем её вообще
|
||||
// Сервер требует либо непустую строку, либо отсутствие поля
|
||||
final dataToSend = (data == null || data.trim().isEmpty) ? null : data;
|
||||
|
||||
return await chatService.sendMessage(
|
||||
slug: slug,
|
||||
data: dataToSend,
|
||||
mediaData: multipartFiles.isEmpty ? null : multipartFiles,
|
||||
socketId: (await SocketIdStorage.getSocketIdFromStorage())!,
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
Future<ChatRoomModel> getChatRoom(String uuid) async {
|
||||
try {
|
||||
return (await chatService.getChatRoom(uuid: uuid));
|
||||
} catch (e, st) {
|
||||
log(e.toString(), stackTrace: st);
|
||||
await Sentry.captureException(e, stackTrace: st);
|
||||
rethrow;
|
||||
}
|
||||
return (await chatService.getChatRoom(uuid: uuid));
|
||||
|
||||
}
|
||||
|
||||
Future<ChatRoomPaginationModel> getChatRooms({String? query, int page = 1}) async {
|
||||
try {
|
||||
return (await chatService.getChatRooms(query: query, page: page));
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
}
|
||||
return (await chatService.getChatRooms(query: query, page: page));
|
||||
|
||||
}
|
||||
|
||||
Future<ChatMessagesModel> getChatMessages(String id, int page) async {
|
||||
try {
|
||||
return (await chatService.getChatMessages(id: id, page: page));
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
}
|
||||
return (await chatService.getChatMessages(id: id, page: page));
|
||||
|
||||
}
|
||||
|
||||
Future<ChatRoomModel> getChatRoomIdByUserSlug({required String slug}) async {
|
||||
try {
|
||||
return (await chatService.getChatRoomIdByUserSlug(user: slug));
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
}
|
||||
return (await chatService.getChatRoomIdByUserSlug(user: slug));
|
||||
|
||||
}
|
||||
|
||||
Future<void> markMessagesAsRead(String id, List<int> messageIds) async {
|
||||
try {
|
||||
await chatService.markMessagesAsRead(id: id, body: {'messages_ids': messageIds});
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
}
|
||||
await chatService.markMessagesAsRead(id: id, body: {'messages_ids': messageIds});
|
||||
|
||||
}
|
||||
|
||||
Future<void> cancelChosenPlan({
|
||||
required int id,
|
||||
}) async {
|
||||
try {
|
||||
await chatService.cancelChosenPlan(id: id);
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
}
|
||||
await chatService.cancelChosenPlan(id: id);
|
||||
|
||||
}
|
||||
|
||||
Future<void> choseStartPlanDate({required int id, required Map<String, String> date}) async {
|
||||
try {
|
||||
await chatService.choseStartPlanDate(id: id, date: date);
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
}
|
||||
await chatService.choseStartPlanDate(id: id, date: date);
|
||||
|
||||
}
|
||||
|
||||
Future<PaymentModel> getPaymentLink({
|
||||
required int id,
|
||||
}) async {
|
||||
try {
|
||||
return await chatService.getPaymentLink(id: id);
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
}
|
||||
return await chatService.getPaymentLink(id: id);
|
||||
|
||||
}
|
||||
|
||||
Future<ChosenPlanModel> getChosenPlan({
|
||||
required int id,
|
||||
}) async {
|
||||
try {
|
||||
return await chatService.getChosenPlan(id: id);
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
}
|
||||
return await chatService.getChosenPlan(id: id);
|
||||
|
||||
}
|
||||
|
||||
Future<void> finishChosenPlan({
|
||||
required int id,
|
||||
}) async {
|
||||
try {
|
||||
await chatService.finishChosenPlan(id: id);
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
}
|
||||
await chatService.finishChosenPlan(id: id);
|
||||
|
||||
}
|
||||
|
||||
Future<void> complainAboutConsultation({
|
||||
required int id,
|
||||
required PlanComplainModel body,
|
||||
}) async {
|
||||
try {
|
||||
await chatService.complainAboutConsultation(id: id, body: body);
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
}
|
||||
await chatService.complainAboutConsultation(id: id, body: body);
|
||||
|
||||
}
|
||||
|
||||
Future<String> getChatByUserSlug(String slug) async {
|
||||
try {
|
||||
final response = await chatService.getChatByUserSlug(slug: slug);
|
||||
if (response.response.statusCode == 404) {
|
||||
return '404';
|
||||
} else {
|
||||
return response.data['id'];
|
||||
}
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
return 'error';
|
||||
final response = await chatService.getChatByUserSlug(slug: slug);
|
||||
if (response.response.statusCode == 404) {
|
||||
return '404';
|
||||
}
|
||||
return response.data['id'];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import 'package:eatvio_app/features/complaining/presentation/complaining_bottom_
|
||||
import 'package:eatvio_app/features/complaining/presentation/cubit/complaining_state.dart';
|
||||
import 'package:eatvio_app/features/complaining/repositories/complaining_repository.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:eatvio_app/core/error_reporting/report_from.dart';
|
||||
|
||||
class ComplainingCubit extends Cubit<ComplainingState> {
|
||||
final ComplainingRepository repository;
|
||||
@@ -81,6 +82,7 @@ class ComplainingCubit extends Cubit<ComplainingState> {
|
||||
}
|
||||
}
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
log(e.toString(), stackTrace: st);
|
||||
}
|
||||
emit(state.copyWith(wasSentSuccessfully: false));
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import 'package:eatvio_app/features/complaining/models/complain_model.dart';
|
||||
import 'package:eatvio_app/features/complaining/services/complaining_service.dart';
|
||||
import 'package:sentry_flutter/sentry_flutter.dart';
|
||||
|
||||
class ComplainingRepository {
|
||||
final ComplainingService service;
|
||||
@@ -11,12 +10,8 @@ class ComplainingRepository {
|
||||
required String category,
|
||||
required ComplainModel body,
|
||||
}) async {
|
||||
try {
|
||||
await service.sendPlanComplain(slug: slug, category: category, body: body);
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
}
|
||||
await service.sendPlanComplain(slug: slug, category: category, body: body);
|
||||
|
||||
}
|
||||
|
||||
Future<void> sendRecipeComplain({
|
||||
@@ -24,12 +19,8 @@ class ComplainingRepository {
|
||||
required String category,
|
||||
required ComplainModel body,
|
||||
}) async {
|
||||
try {
|
||||
await service.sendRecipeComplain(slug: slug, category: category, body: body);
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
}
|
||||
await service.sendRecipeComplain(slug: slug, category: category, body: body);
|
||||
|
||||
}
|
||||
|
||||
Future<void> sendBlogPostsComplain({
|
||||
@@ -37,12 +28,8 @@ class ComplainingRepository {
|
||||
required String category,
|
||||
required ComplainModel body,
|
||||
}) async {
|
||||
try {
|
||||
await service.sendBlogPostsComplain(id: id, category: category, body: body);
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
}
|
||||
await service.sendBlogPostsComplain(id: id, category: category, body: body);
|
||||
|
||||
}
|
||||
|
||||
Future<void> sendProfileComplain({
|
||||
@@ -50,12 +37,8 @@ class ComplainingRepository {
|
||||
required String category,
|
||||
required ComplainModel body,
|
||||
}) async {
|
||||
try {
|
||||
await service.sendProfileComplain(slug: slug, category: category, body: body);
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
}
|
||||
await service.sendProfileComplain(slug: slug, category: category, body: body);
|
||||
|
||||
}
|
||||
|
||||
Future<void> sendDietComplain({
|
||||
@@ -63,12 +46,8 @@ class ComplainingRepository {
|
||||
required String category,
|
||||
required ComplainModel body,
|
||||
}) async {
|
||||
try {
|
||||
await service.sendDietComplain(id: id, category: category, body: body);
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
}
|
||||
await service.sendDietComplain(id: id, category: category, body: body);
|
||||
|
||||
}
|
||||
|
||||
Future<void> sendCommentComplain({
|
||||
@@ -76,11 +55,7 @@ class ComplainingRepository {
|
||||
required String category,
|
||||
required ComplainModel body,
|
||||
}) async {
|
||||
try {
|
||||
await service.sendCommentComplain(id: id, category: category, body: body);
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
}
|
||||
await service.sendCommentComplain(id: id, category: category, body: body);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import 'package:eatvio_app/features/consultant/become_consultant/models/consulta
|
||||
import 'package:eatvio_app/features/consultant/become_consultant/presentation/bloc/register_consultant_cubit/register_consultant_state.dart';
|
||||
import 'package:eatvio_app/features/consultant/become_consultant/repositories/consultant_repository.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:eatvio_app/core/error_reporting/report_from.dart';
|
||||
|
||||
class RegisterConsultantCubit extends Cubit<RegisterConsultantState> {
|
||||
final ConsultantRepository consultantRepository;
|
||||
@@ -54,45 +55,73 @@ class RegisterConsultantCubit extends Cubit<RegisterConsultantState> {
|
||||
requestModel: myRequestStatus,
|
||||
certPhotos: certPhotos,
|
||||
isUpdating: _update,
|
||||
error: null,
|
||||
),
|
||||
);
|
||||
} catch (e) {
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
log(e.toString());
|
||||
emit(state.copyWith(loading: false, error: e.toString()));
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> disableLoading() async {
|
||||
try {
|
||||
final certPhotos = await consultantRepository.getConsultantCertPhotos();
|
||||
emit(state.copyWith(loading: false, certPhotos: certPhotos));
|
||||
} catch (e) {
|
||||
emit(state.copyWith(loading: false, certPhotos: certPhotos, error: null));
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
log(e.toString());
|
||||
emit(state.copyWith(loading: false, error: e.toString()));
|
||||
}
|
||||
}
|
||||
|
||||
/// Повторная загрузка после [DataErrorWidget], аналогично [AboutDietCubit.getDiet].
|
||||
Future<void> reloadData(String? slug) async {
|
||||
emit(state.copyWith(loading: true, error: null));
|
||||
if (slug != null) {
|
||||
await getMyRequestStatus(slug);
|
||||
} else {
|
||||
await disableLoading();
|
||||
}
|
||||
}
|
||||
|
||||
void updateConsultantProfileModel(ConsultantProfileModel consultant, [bool acceptOffer = false]) {
|
||||
emit(state.copyWith(consultant: consultant, acceptOffer: acceptOffer, loading: false));
|
||||
emit(state.copyWith(consultant: consultant, acceptOffer: acceptOffer, loading: false, error: null));
|
||||
}
|
||||
|
||||
Future<void> registerConsultant() async {
|
||||
if (state.newAddedPhotos.isNotEmpty) {
|
||||
await consultantRepository.storeConsultantCertPhotos(files: state.newAddedPhotos);
|
||||
}
|
||||
if (state.deletedPhotoIds.isNotEmpty) {
|
||||
for (final int id in state.deletedPhotoIds) {
|
||||
await consultantRepository.deletePhoto(id);
|
||||
emit(state.copyWith(error: null));
|
||||
try {
|
||||
if (state.newAddedPhotos.isNotEmpty) {
|
||||
await consultantRepository.storeConsultantCertPhotos(files: state.newAddedPhotos);
|
||||
}
|
||||
if (state.deletedPhotoIds.isNotEmpty) {
|
||||
for (final int id in state.deletedPhotoIds) {
|
||||
await consultantRepository.deletePhoto(id);
|
||||
}
|
||||
}
|
||||
await consultantRepository.registerConsultant(consultant: state.consultant, update: _update);
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
log(e.toString());
|
||||
emit(state.copyWith(error: e.toString()));
|
||||
}
|
||||
await consultantRepository.registerConsultant(consultant: state.consultant, update: _update);
|
||||
}
|
||||
|
||||
Future<void> addCertPhotos(List<File> files) async {
|
||||
if (files.isEmpty) {
|
||||
return;
|
||||
}
|
||||
final compressedFiles = await ImageCompressUtility.compressFilesList(files);
|
||||
try {
|
||||
final compressedFiles = await ImageCompressUtility.compressFilesList(files);
|
||||
|
||||
emit(state.copyWith(newAddedPhotos: [...state.newAddedPhotos, ...compressedFiles]));
|
||||
emit(state.copyWith(newAddedPhotos: [...state.newAddedPhotos, ...compressedFiles], error: null));
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
log(e.toString());
|
||||
emit(state.copyWith(error: e.toString()));
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> removeCertPhoto(int? id, String? path) async {
|
||||
|
||||
@@ -18,5 +18,6 @@ abstract class RegisterConsultantState with _$RegisterConsultantState {
|
||||
@Default(<ConsultantCertPhotoModel>[]) List<ConsultantCertPhotoModel> certPhotos,
|
||||
@Default(<File>[]) List<File> newAddedPhotos,
|
||||
@Default(<int>[]) List<int> deletedPhotoIds,
|
||||
String? error,
|
||||
}) = _RegisterConsultantState;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import 'package:eatvio_app/core/utils/image_constant.dart';
|
||||
import 'package:eatvio_app/core/widgets/data_error_widget.dart';
|
||||
import 'package:eatvio_app/core/widgets/loader.dart';
|
||||
import 'package:eatvio_app/features/consultant/become_consultant/presentation/bloc/register_consultant_cubit/register_consultant_cubit.dart';
|
||||
import 'package:eatvio_app/features/consultant/become_consultant/presentation/bloc/register_consultant_cubit/register_consultant_state.dart';
|
||||
@@ -9,6 +10,7 @@ import 'package:eatvio_app/features/consultant/become_consultant/presentation/pa
|
||||
import 'package:eatvio_app/features/consultant/become_consultant/presentation/pages/registration_as_screen.dart';
|
||||
import 'package:eatvio_app/features/consultant/become_consultant/presentation/pages/social_networks_screen.dart';
|
||||
import 'package:eatvio_app/core/locator_service.dart';
|
||||
import 'package:eatvio_app/core/theme/custom_text_style.dart';
|
||||
import 'package:eatvio_app/core/theme/theme_helper.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
@@ -48,8 +50,37 @@ class _StepperBecomeConsultantScreenState extends State<StepperBecomeConsultantS
|
||||
create: (context) => registrationConsultantCubit,
|
||||
child: BlocBuilder<RegisterConsultantCubit, RegisterConsultantState>(
|
||||
builder: (context, state) {
|
||||
if (state.loading == false) {
|
||||
if (state.loading) {
|
||||
return const Scaffold(body: Loader());
|
||||
}
|
||||
if (state.error != null) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
centerTitle: true,
|
||||
leading: BackButton(
|
||||
onPressed: () {
|
||||
if (context.canPop()) {
|
||||
GoRouter.of(context).pop();
|
||||
return;
|
||||
}
|
||||
GoRouter.of(context).go('/feed-screen');
|
||||
},
|
||||
),
|
||||
title: Text(
|
||||
'',
|
||||
maxLines: 2,
|
||||
textAlign: TextAlign.center,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
softWrap: true,
|
||||
style: TextStyles.headingXLSemibold.copyWith(color: appTheme.black),
|
||||
),
|
||||
),
|
||||
body: DataErrorWidget(
|
||||
onReload: () => context.read<RegisterConsultantCubit>().reloadData(widget.slug),
|
||||
),
|
||||
);
|
||||
}
|
||||
return Scaffold(
|
||||
floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat,
|
||||
floatingActionButton: Row(
|
||||
children: [
|
||||
@@ -136,6 +167,9 @@ class _StepperBecomeConsultantScreenState extends State<StepperBecomeConsultantS
|
||||
try {
|
||||
await registrationConsultantCubit.registerConsultant();
|
||||
if (!context.mounted) return;
|
||||
if (registrationConsultantCubit.state.error != null) {
|
||||
return;
|
||||
}
|
||||
await showModalBottomSheet(
|
||||
useRootNavigator: true,
|
||||
showDragHandle: true,
|
||||
@@ -183,7 +217,7 @@ class _StepperBecomeConsultantScreenState extends State<StepperBecomeConsultantS
|
||||
);
|
||||
} catch (e) {
|
||||
if (!context.mounted) return;
|
||||
showDialog(
|
||||
showDialog<void>(
|
||||
context: context,
|
||||
builder: (context) => AlertDialog(
|
||||
actionsPadding: const EdgeInsets.symmetric(horizontal: 4),
|
||||
@@ -191,9 +225,7 @@ class _StepperBecomeConsultantScreenState extends State<StepperBecomeConsultantS
|
||||
actions: [
|
||||
TextButton(
|
||||
child: const Text('Ок'),
|
||||
onPressed: () {
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
onPressed: () => Navigator.of(context).pop(),
|
||||
),
|
||||
],
|
||||
),
|
||||
@@ -282,9 +314,6 @@ class _StepperBecomeConsultantScreenState extends State<StepperBecomeConsultantS
|
||||
],
|
||||
),
|
||||
);
|
||||
} else {
|
||||
return const Scaffold(body: Loader());
|
||||
}
|
||||
},
|
||||
),
|
||||
);
|
||||
|
||||
@@ -5,7 +5,6 @@ import 'package:eatvio_app/features/consultant/become_consultant/models/consulta
|
||||
import 'package:eatvio_app/features/consultant/become_consultant/models/consultation_request_model.dart';
|
||||
import 'package:eatvio_app/features/consultant/become_consultant/services/consultant_service.dart';
|
||||
import 'package:http_parser/http_parser.dart';
|
||||
import 'package:sentry_flutter/sentry_flutter.dart';
|
||||
|
||||
class ConsultantRepository {
|
||||
final ConsultantService consultantService;
|
||||
@@ -13,90 +12,58 @@ class ConsultantRepository {
|
||||
const ConsultantRepository({required this.consultantService});
|
||||
|
||||
Future<void> registerConsultant({required ConsultantProfileModel consultant, bool update = false}) async {
|
||||
try {
|
||||
if (update) {
|
||||
return await consultantService.consultantUpdate(consultantModel: consultant);
|
||||
} else {
|
||||
return await consultantService.consultantRegistration(consultantModel: consultant);
|
||||
}
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
if (update) {
|
||||
return await consultantService.consultantUpdate(consultantModel: consultant);
|
||||
} else {
|
||||
return await consultantService.consultantRegistration(consultantModel: consultant);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Future<ConsultationRequestModel> getConsultantRequestStatus(String slug) async {
|
||||
try {
|
||||
return await consultantService.getConsultantRequestStatus(slug: slug);
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
}
|
||||
return await consultantService.getConsultantRequestStatus(slug: slug);
|
||||
|
||||
}
|
||||
|
||||
Future<ConsultationRequestModel> getMyRequestStatus(String slug) async {
|
||||
try {
|
||||
return await consultantService.getMyRequestStatus(slug: slug);
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
}
|
||||
return await consultantService.getMyRequestStatus(slug: slug);
|
||||
|
||||
}
|
||||
|
||||
Future<List<ConsultantCertPhotoModel>> getConsultantCertPhotos() async {
|
||||
try {
|
||||
return await consultantService.getConsultantCertPhotos();
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
}
|
||||
return await consultantService.getConsultantCertPhotos();
|
||||
|
||||
}
|
||||
|
||||
Future<List<ConsultantCertPhotoModel>> storeConsultantCertPhotos({required List<File> files}) async {
|
||||
try {
|
||||
final multipartFiles = <MultipartFile>[];
|
||||
final multipartFiles = <MultipartFile>[];
|
||||
|
||||
for (final file in files) {
|
||||
final fileBytes = await file.readAsBytes();
|
||||
final multipartFile = MultipartFile.fromBytes(fileBytes, filename: file.path.split('/').last, contentType: MediaType('application', 'octet-stream'));
|
||||
multipartFiles.add(multipartFile);
|
||||
}
|
||||
|
||||
if (multipartFiles.isEmpty) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return await consultantService.storeConsultantCertPhotos(photos: multipartFiles);
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
for (final file in files) {
|
||||
final fileBytes = await file.readAsBytes();
|
||||
final multipartFile = MultipartFile.fromBytes(fileBytes, filename: file.path.split('/').last, contentType: MediaType('application', 'octet-stream'));
|
||||
multipartFiles.add(multipartFile);
|
||||
}
|
||||
|
||||
if (multipartFiles.isEmpty) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return await consultantService.storeConsultantCertPhotos(photos: multipartFiles);
|
||||
|
||||
}
|
||||
|
||||
Future<void> hideConsultantCertPhoto(int id) async {
|
||||
try {
|
||||
await consultantService.hideConsultantCertPhoto(payload: {'cert_photo_id': id});
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
}
|
||||
await consultantService.hideConsultantCertPhoto(payload: {'cert_photo_id': id});
|
||||
|
||||
}
|
||||
|
||||
Future<void> unHideConsultantCertPhoto(int id) async {
|
||||
try {
|
||||
await consultantService.unHideConsultantCertPhoto(payload: {'cert_photo_id': id});
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
}
|
||||
await consultantService.unHideConsultantCertPhoto(payload: {'cert_photo_id': id});
|
||||
|
||||
}
|
||||
|
||||
Future<void> deletePhoto(int id) async {
|
||||
try {
|
||||
await consultantService.deletePhoto(id: id);
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
}
|
||||
await consultantService.deletePhoto(id: id);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import 'package:eatvio_app/features/consultant_rating/repositories/consultant_ra
|
||||
import 'package:eatvio_app/features/feed/repositories/feed_repository.dart';
|
||||
import 'package:eatvio_app/features/profile/repositories/profile_repository.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:eatvio_app/core/error_reporting/report_from.dart';
|
||||
|
||||
class ConsultantRatingCubit extends Cubit<ConsultantRatingState> {
|
||||
final ConsultantRatingRepository repository;
|
||||
@@ -20,6 +21,7 @@ class ConsultantRatingCubit extends Cubit<ConsultantRatingState> {
|
||||
final absoluteRating = await feedRepository.getConsultants((await profileRepository.getMyProfile()).name);
|
||||
emit(state.copyWith(isStatisticsLoading: false, statistics: statistics, error: null, absoluteRating: absoluteRating.first.totalScores));
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
emit(state.copyWith(isStatisticsLoading: true, error: e.toString()));
|
||||
log(e.toString(), stackTrace: st);
|
||||
}
|
||||
@@ -31,6 +33,7 @@ class ConsultantRatingCubit extends Cubit<ConsultantRatingState> {
|
||||
final scoreLogs = await repository.getScoreLogs(date: date);
|
||||
emit(state.copyWith(isRatingLoading: false, ratings: scoreLogs, error: null));
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
emit(state.copyWith(isRatingLoading: true, error: e.toString()));
|
||||
log(e.toString(), stackTrace: st);
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import 'package:eatvio_app/features/consultant_rating/models/rating_model.dart';
|
||||
import 'package:eatvio_app/features/consultant_rating/models/statistics_model.dart';
|
||||
import 'package:eatvio_app/features/consultant_rating/services/consultant_rating_service.dart';
|
||||
import 'package:sentry_flutter/sentry_flutter.dart';
|
||||
|
||||
class ConsultantRatingRepository {
|
||||
final ConsultantRatingService service;
|
||||
@@ -9,21 +8,13 @@ class ConsultantRatingRepository {
|
||||
ConsultantRatingRepository(this.service);
|
||||
|
||||
Future<StatisticsModel> getConsultantStatistics({String? date}) async {
|
||||
try {
|
||||
return await service.getConsultantStatistics(date: date);
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
}
|
||||
return await service.getConsultantStatistics(date: date);
|
||||
|
||||
}
|
||||
|
||||
Future<List<RatingModel>> getScoreLogs({String? date}) async {
|
||||
try {
|
||||
final data = (await service.getScoreLogs(date: date)).data;
|
||||
return data;
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
}
|
||||
final data = (await service.getScoreLogs(date: date)).data;
|
||||
return data;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import 'package:eatvio_app/core/enums/base_state.dart';
|
||||
import 'package:eatvio_app/features/consultations/presentation/cubit/consultations_state.dart';
|
||||
import 'package:eatvio_app/features/consultations/repositories/consultations_repository.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:eatvio_app/core/error_reporting/report_from.dart';
|
||||
|
||||
class ConsultationsCubit extends Cubit<ConsultationsState> {
|
||||
final ConsultationsRepository consultationsRepository;
|
||||
@@ -14,6 +15,7 @@ class ConsultationsCubit extends Cubit<ConsultationsState> {
|
||||
final consultations = await consultationsRepository.getConsultations();
|
||||
emit(state.copyWith(consultations: consultations, state: BaseState.success));
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
log(e.toString(), stackTrace: st);
|
||||
emit(state.copyWith(state: BaseState.error));
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import 'package:eatvio_app/core/enums/filters_comparison_enum.dart';
|
||||
import 'package:eatvio_app/features/consultations/models/consultation_model.dart';
|
||||
import 'package:eatvio_app/features/consultations/services/consultation_service.dart';
|
||||
import 'package:sentry_flutter/sentry_flutter.dart';
|
||||
import 'package:eatvio_app/features/finances_and_consultations_archive/models/consultant_finance_model.dart';
|
||||
import 'package:eatvio_app/features/finances_and_consultations_archive/models/statistic_model.dart';
|
||||
import 'package:eatvio_app/features/finances_and_consultations_archive/models/user_purchases_model.dart';
|
||||
@@ -11,13 +10,8 @@ class ConsultationsRepository {
|
||||
|
||||
ConsultationsRepository({required this.consultationService});
|
||||
Future<List<ConsultationModel>> getConsultations() async {
|
||||
try {
|
||||
final consultations = await consultationService.getConsultations();
|
||||
return consultations.data;
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
}
|
||||
final consultations = await consultationService.getConsultations();
|
||||
return consultations.data;
|
||||
}
|
||||
|
||||
Future<List<ConsultationModel>> getFilteredConsultations({
|
||||
@@ -26,44 +20,24 @@ class ConsultationsRepository {
|
||||
FiltersComparisonEnum? stateComparison,
|
||||
FiltersComparisonEnum? dateComparison,
|
||||
}) async {
|
||||
try {
|
||||
final model = await consultationService.getFilteredConsultations(
|
||||
state: state,
|
||||
date: date,
|
||||
stateComparison: stateComparison,
|
||||
dateComparison: dateComparison,
|
||||
);
|
||||
return model.data;
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
}
|
||||
final model = await consultationService.getFilteredConsultations(
|
||||
state: state,
|
||||
date: date,
|
||||
stateComparison: stateComparison,
|
||||
dateComparison: dateComparison,
|
||||
);
|
||||
return model.data;
|
||||
}
|
||||
|
||||
Future<StatisticModel> getStatistic() async {
|
||||
try {
|
||||
return await consultationService.getStatistics();
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
}
|
||||
return consultationService.getStatistics();
|
||||
}
|
||||
|
||||
Future<List<ConsultantFinanceModel>> getConsultantFinances(String? date, FiltersComparisonEnum? dateComparison) async {
|
||||
try {
|
||||
return await consultationService.getConsultantFinances(date, dateComparison);
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
}
|
||||
return consultationService.getConsultantFinances(date, dateComparison);
|
||||
}
|
||||
|
||||
Future<List<UserPurchasesModel>> getUserPurchases(String? date, FiltersComparisonEnum? dateComparison) async {
|
||||
try {
|
||||
return await consultationService.getUserPurchases(date, dateComparison);
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
}
|
||||
return consultationService.getUserPurchases(date, dateComparison);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,9 +13,9 @@ import 'package:eatvio_app/features/glossary/models/glossary_model.dart';
|
||||
import 'package:eatvio_app/features/glossary/repositories/glossary_repository.dart';
|
||||
import 'package:eatvio_app/features/profile/repositories/profile_repository.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:eatvio_app/core/error_reporting/report_from.dart';
|
||||
import 'package:flutter_image_compress/flutter_image_compress.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'package:sentry_flutter/sentry_flutter.dart';
|
||||
import 'package:path_provider/path_provider.dart';
|
||||
|
||||
class CreateDietCubit extends Cubit<CreateDietState> {
|
||||
@@ -29,9 +29,10 @@ class CreateDietCubit extends Cubit<CreateDietState> {
|
||||
|
||||
Future<void> setInitialData(Diet? diet) async {
|
||||
if (diet == null) return;
|
||||
emit(state.copyWith(isLoading: true, isDietBeingEdited: true));
|
||||
dietId = diet.id;
|
||||
final dailyScheduleWithNutrition = await createDietRepository.getDietPortionsNutrition(diet.id);
|
||||
try {
|
||||
emit(state.copyWith(isLoading: true, isDietBeingEdited: true));
|
||||
dietId = diet.id;
|
||||
final dailyScheduleWithNutrition = await createDietRepository.getDietPortionsNutrition(diet.id);
|
||||
final countOfDays = diet.duration;
|
||||
final List<List<List<DailySchedule>>> dailySchedule = List.generate(countOfDays, (index) => [[], [], [], [], []]);
|
||||
|
||||
@@ -66,7 +67,11 @@ class CreateDietCubit extends Cubit<CreateDietState> {
|
||||
imageUrl: appConfig.buildType == AppBuildType.tests ? null : imageUrl,
|
||||
),
|
||||
);
|
||||
emit(state.copyWith(isLoading: false, isDietBeingEdited: false, dietState: diet.state, durationIndex: durationValues.indexOf(diet.duration)));
|
||||
emit(state.copyWith(isLoading: false, isDietBeingEdited: false, dietState: diet.state, durationIndex: durationValues.indexOf(diet.duration)));
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
emit(state.copyWith(isLoading: false, isDietBeingEdited: false));
|
||||
}
|
||||
}
|
||||
|
||||
void setDetails(String text) {
|
||||
@@ -112,7 +117,12 @@ class CreateDietCubit extends Cubit<CreateDietState> {
|
||||
}
|
||||
|
||||
Future<List<GlossaryModel>> getGlossaryListByQuery(String query) async {
|
||||
return await glossaryRepository.getGlossaryListByQuery(query);
|
||||
try {
|
||||
return await glossaryRepository.getGlossaryListByQuery(query);
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
void setImage(XFile? image, {String? imageUrl}) {
|
||||
@@ -204,7 +214,8 @@ class CreateDietCubit extends Cubit<CreateDietState> {
|
||||
|
||||
Future<Diet?> getDietForPreview() async {
|
||||
if (!_isFormValidForDraft()) return null;
|
||||
final authorProfile = await profileRepository.getMyProfile();
|
||||
try {
|
||||
final authorProfile = await profileRepository.getMyProfile();
|
||||
final imageBytes = (await state.dietData.image?.readAsBytes()) ?? <int>[];
|
||||
String image = '';
|
||||
if (imageBytes.isNotEmpty && imageBytes.length <= _maxImageBytesForBase64) {
|
||||
@@ -297,19 +308,26 @@ class CreateDietCubit extends Cubit<CreateDietState> {
|
||||
isFavorite: false,
|
||||
dailyNutrition: dailyNutrition,
|
||||
);
|
||||
return diet;
|
||||
return diet;
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
Future<File> downloadImageAsFile(String imageUrl) async {
|
||||
final response = await http.get(Uri.parse(imageUrl));
|
||||
|
||||
if (response.statusCode == 200) {
|
||||
Future<File?> downloadImageAsFile(String imageUrl) async {
|
||||
try {
|
||||
final response = await http.get(Uri.parse(imageUrl));
|
||||
if (response.statusCode != 200) {
|
||||
throw Exception('Не удалось загрузить изображение');
|
||||
}
|
||||
final tempDir = await getTemporaryDirectory();
|
||||
final filePath = '${tempDir.path}/${imageUrl.split('/').last}';
|
||||
final file = File(filePath);
|
||||
return await file.writeAsBytes(response.bodyBytes);
|
||||
} else {
|
||||
throw Exception('Не удалось загрузить изображение');
|
||||
return file.writeAsBytes(response.bodyBytes);
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -353,7 +371,7 @@ class CreateDietCubit extends Cubit<CreateDietState> {
|
||||
emit(state.copyWith(published: dietState != DietState.draft, drafted: dietState == DietState.draft));
|
||||
return null;
|
||||
} catch (e, st) {
|
||||
await Sentry.captureException(e, stackTrace: st);
|
||||
await reportFrom(e, st, this);
|
||||
log(e.toString(), stackTrace: st);
|
||||
emit(state.copyWith(isDietPublishing: false));
|
||||
}
|
||||
@@ -391,7 +409,7 @@ class CreateDietCubit extends Cubit<CreateDietState> {
|
||||
emit(state.copyWith(isDietBeingEdited: false));
|
||||
return null;
|
||||
} catch (e, st) {
|
||||
await Sentry.captureException(e, stackTrace: st);
|
||||
await reportFrom(e, st, this);
|
||||
log(e.toString(), stackTrace: st);
|
||||
emit(state.copyWith(isDietBeingEdited: false));
|
||||
return 'error';
|
||||
|
||||
@@ -2,7 +2,6 @@ import 'dart:io';
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:eatvio_app/features/create_diet/services/create_diet_service.dart';
|
||||
import 'package:eatvio_app/features/feed/models/diets_pagination_model.dart';
|
||||
import 'package:sentry_flutter/sentry_flutter.dart';
|
||||
|
||||
class CreateDietRepository {
|
||||
final CreateDietService createDietService;
|
||||
@@ -62,48 +61,40 @@ class CreateDietRepository {
|
||||
dietMap.addAll({'name': name, 'duration': duration});
|
||||
|
||||
final formData = FormData.fromMap(dietMap);
|
||||
try {
|
||||
switch (state) {
|
||||
case DietState.active:
|
||||
return await createDietService.createPublishedDiet(formData: formData);
|
||||
case DietState.draft:
|
||||
return await createDietService.createDraftedDiet(formData: formData);
|
||||
case DietState.personal:
|
||||
return await createDietService.createPersonalDiet(formData: formData);
|
||||
}
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
switch (state) {
|
||||
case DietState.active:
|
||||
return await createDietService.createPublishedDiet(formData: formData);
|
||||
case DietState.draft:
|
||||
return await createDietService.createDraftedDiet(formData: formData);
|
||||
case DietState.personal:
|
||||
return await createDietService.createPersonalDiet(formData: formData);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Future<Map<int, Map<int, Map<int, DailySchedule>>>> getDietPortionsNutrition(int dietId) async {
|
||||
try {
|
||||
final response = await createDietService.getDietPortionsNutrition(diet: dietId);
|
||||
final data = response.data;
|
||||
final dailySchedule = (data as Map<String, dynamic>).map((key, value) {
|
||||
return MapEntry(
|
||||
int.parse(key),
|
||||
(value as Map<String, dynamic>).map((key, value) {
|
||||
return MapEntry(
|
||||
int.parse(key),
|
||||
(value as Map<String, dynamic>).map((key, value) {
|
||||
final portionMap = Map<String, dynamic>.from(value as Map<String, dynamic>);
|
||||
final pnvid = portionMap['product_nutritional_value_id'];
|
||||
if (pnvid is String) {
|
||||
portionMap['product_nutritional_value_id'] = int.tryParse(pnvid);
|
||||
}
|
||||
return MapEntry(int.parse(key), DailySchedule.fromJson(portionMap));
|
||||
}),
|
||||
);
|
||||
}),
|
||||
);
|
||||
});
|
||||
return dailySchedule;
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
}
|
||||
final response = await createDietService.getDietPortionsNutrition(diet: dietId);
|
||||
final data = response.data;
|
||||
final dailySchedule = (data as Map<String, dynamic>).map((key, value) {
|
||||
return MapEntry(
|
||||
int.parse(key),
|
||||
(value as Map<String, dynamic>).map((key, value) {
|
||||
return MapEntry(
|
||||
int.parse(key),
|
||||
(value as Map<String, dynamic>).map((key, value) {
|
||||
final portionMap = Map<String, dynamic>.from(value as Map<String, dynamic>);
|
||||
final pnvid = portionMap['product_nutritional_value_id'];
|
||||
if (pnvid is String) {
|
||||
portionMap['product_nutritional_value_id'] = int.tryParse(pnvid);
|
||||
}
|
||||
return MapEntry(int.parse(key), DailySchedule.fromJson(portionMap));
|
||||
}),
|
||||
);
|
||||
}),
|
||||
);
|
||||
});
|
||||
return dailySchedule;
|
||||
|
||||
}
|
||||
|
||||
Future<int> updateDiet({
|
||||
@@ -161,23 +152,16 @@ class CreateDietRepository {
|
||||
}
|
||||
|
||||
final formData = FormData.fromMap(dietMap);
|
||||
try {
|
||||
switch (state) {
|
||||
case DietState.active:
|
||||
final response = await createDietService.updatePublished(diet: dietId, formData: formData);
|
||||
return response.response.statusCode ?? 0;
|
||||
case DietState.draft:
|
||||
final response = await createDietService.updateDrafted(diet: dietId, formData: formData);
|
||||
return response.response.statusCode ?? 0;
|
||||
case DietState.personal:
|
||||
final response = await createDietService.updatePersonal(diet: dietId, formData: formData);
|
||||
return response.response.statusCode ?? 0;
|
||||
}
|
||||
} on DioException catch (e) {
|
||||
return e.response?.statusCode ?? 0;
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
switch (state) {
|
||||
case DietState.active:
|
||||
final response = await createDietService.updatePublished(diet: dietId, formData: formData);
|
||||
return response.response.statusCode ?? 0;
|
||||
case DietState.draft:
|
||||
final response = await createDietService.updateDrafted(diet: dietId, formData: formData);
|
||||
return response.response.statusCode ?? 0;
|
||||
case DietState.personal:
|
||||
final response = await createDietService.updatePersonal(diet: dietId, formData: formData);
|
||||
return response.response.statusCode ?? 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ import 'package:eatvio_app/core/image_compressing/image_compress_utility.dart';
|
||||
import 'package:eatvio_app/features/create_plan/presentation/cubit/create_plan_state.dart';
|
||||
import 'package:eatvio_app/features/create_plan/repositories/create_plan_repository.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:eatvio_app/core/error_reporting/report_from.dart';
|
||||
import 'package:flutter_image_compress/flutter_image_compress.dart';
|
||||
|
||||
class CreatePlanCubit extends Cubit<CreatePlanState> {
|
||||
@@ -457,7 +458,8 @@ class CreatePlanCubit extends Cubit<CreatePlanState> {
|
||||
await createPlanRepository.createPlan(model: planMap);
|
||||
emit(state.copyWith(isLoading: false, planCreated: true));
|
||||
}
|
||||
} catch (e) {
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
log(e.toString());
|
||||
emit(state.copyWith(isLoading: false, planCreated: true));
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:eatvio_app/features/create_plan/services/create_plan_service.dart';
|
||||
import 'package:sentry_flutter/sentry_flutter.dart';
|
||||
|
||||
class CreatePlanRepository {
|
||||
final CreatePlanService createPlanService;
|
||||
@@ -10,13 +9,9 @@ class CreatePlanRepository {
|
||||
Future<void> createPlan({
|
||||
required Map<String, dynamic> model,
|
||||
}) async {
|
||||
try {
|
||||
final formData = FormData.fromMap(model);
|
||||
return await createPlanService.createPlan(formData: formData);
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
}
|
||||
final formData = FormData.fromMap(model);
|
||||
return await createPlanService.createPlan(formData: formData);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ import 'package:eatvio_app/features/feed/models/recipes_model.dart';
|
||||
import 'package:eatvio_app/features/glossary/models/glossary_model.dart';
|
||||
import 'package:eatvio_app/features/glossary/repositories/glossary_repository.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:sentry_flutter/sentry_flutter.dart';
|
||||
import 'package:eatvio_app/core/error_reporting/report_from.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'package:path_provider/path_provider.dart';
|
||||
|
||||
@@ -166,7 +166,7 @@ class CreateRecipeCubit extends Cubit<CreateRecipeState> {
|
||||
await recipeRepository.publishRecipe(model, update, slug);
|
||||
return true;
|
||||
} catch (e, st) {
|
||||
await Sentry.captureException(e, stackTrace: st);
|
||||
await reportFrom(e, st, this);
|
||||
log(e.toString(), stackTrace: st);
|
||||
return false;
|
||||
}
|
||||
@@ -179,7 +179,7 @@ class CreateRecipeCubit extends Cubit<CreateRecipeState> {
|
||||
emit(state.copyWith(drafted: true));
|
||||
return true;
|
||||
} catch (e, st) {
|
||||
await Sentry.captureException(e, stackTrace: st);
|
||||
await reportFrom(e, st, this);
|
||||
log(e.toString(), stackTrace: st);
|
||||
return false;
|
||||
}
|
||||
@@ -204,16 +204,19 @@ class CreateRecipeCubit extends Cubit<CreateRecipeState> {
|
||||
));
|
||||
}
|
||||
|
||||
Future<File> downloadImageAsFile(String imageUrl) async {
|
||||
final response = await http.get(Uri.parse(imageUrl));
|
||||
|
||||
if (response.statusCode == 200) {
|
||||
Future<File?> downloadImageAsFile(String imageUrl) async {
|
||||
try {
|
||||
final response = await http.get(Uri.parse(imageUrl));
|
||||
if (response.statusCode != 200) {
|
||||
throw Exception('Не удалось загрузить изображение');
|
||||
}
|
||||
final tempDir = await getTemporaryDirectory();
|
||||
final filePath = '${tempDir.path}/${imageUrl.split('/').last}';
|
||||
final file = File(filePath);
|
||||
return await file.writeAsBytes(response.bodyBytes);
|
||||
} else {
|
||||
throw Exception('Не удалось загрузить изображение');
|
||||
return file.writeAsBytes(response.bodyBytes);
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -222,44 +225,53 @@ class CreateRecipeCubit extends Cubit<CreateRecipeState> {
|
||||
}
|
||||
|
||||
Future<void> recipeToEntity(Recipe recipe) async {
|
||||
final file = await downloadImageAsFile('${sl<AppConfig>().baseUrl}/storage/${recipe.image}');
|
||||
try {
|
||||
final file = await downloadImageAsFile('${sl<AppConfig>().baseUrl}/storage/${recipe.image}');
|
||||
if (file == null) {
|
||||
disableLoading();
|
||||
return;
|
||||
}
|
||||
|
||||
final List<StepEntity> steps = await Future.wait(
|
||||
recipe.steps!.map(
|
||||
(e) async => StepEntity(
|
||||
description: e.description,
|
||||
image: e.image.isEmpty ? null : await downloadImageAsFile('${sl<AppConfig>().baseUrl}/storage/${e.image}'),
|
||||
final List<StepEntity> steps = await Future.wait(
|
||||
recipe.steps!.map(
|
||||
(e) async => StepEntity(
|
||||
description: e.description,
|
||||
image: e.image.isEmpty ? null : await downloadImageAsFile('${sl<AppConfig>().baseUrl}/storage/${e.image}'),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
emit(
|
||||
CreateRecipeState(
|
||||
entity: RecipeCreateEntity(
|
||||
title: recipe.title,
|
||||
typeOfRecipe: TypeOfRecipe.fromApiType(recipe.type!),
|
||||
countOfPortions: recipe.servings,
|
||||
energyInOnePortion: recipe.calories,
|
||||
totalCookHours: recipe.cookingTime ~/ 60,
|
||||
totalCookMinutes: recipe.cookingTime % 60,
|
||||
activeCookHours: recipe.activeCookingTime ~/ 60,
|
||||
activeCookMinutes: recipe.activeCookingTime % 60,
|
||||
description: recipe.description,
|
||||
image: file,
|
||||
videoUrl: recipe.videoUrl,
|
||||
ingredients: recipe.ingredients!
|
||||
.map((e) => i.Ingredient(
|
||||
name: e.name,
|
||||
unit: e.unit!,
|
||||
portion: e.portion,
|
||||
productId: e.productId,
|
||||
))
|
||||
.toList(),
|
||||
steps: steps,
|
||||
tags: recipe.tags.map((e) => (e.name)).toList(),
|
||||
);
|
||||
emit(
|
||||
CreateRecipeState(
|
||||
entity: RecipeCreateEntity(
|
||||
title: recipe.title,
|
||||
typeOfRecipe: TypeOfRecipe.fromApiType(recipe.type!),
|
||||
countOfPortions: recipe.servings,
|
||||
energyInOnePortion: recipe.calories,
|
||||
totalCookHours: recipe.cookingTime ~/ 60,
|
||||
totalCookMinutes: recipe.cookingTime % 60,
|
||||
activeCookHours: recipe.activeCookingTime ~/ 60,
|
||||
activeCookMinutes: recipe.activeCookingTime % 60,
|
||||
description: recipe.description,
|
||||
image: file,
|
||||
videoUrl: recipe.videoUrl,
|
||||
ingredients: recipe.ingredients!
|
||||
.map((e) => i.Ingredient(
|
||||
name: e.name,
|
||||
unit: e.unit!,
|
||||
portion: e.portion,
|
||||
productId: e.productId,
|
||||
))
|
||||
.toList(),
|
||||
steps: steps,
|
||||
tags: recipe.tags.map((e) => (e.name)).toList(),
|
||||
),
|
||||
loading: false,
|
||||
),
|
||||
loading: false,
|
||||
),
|
||||
);
|
||||
);
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
disableLoading();
|
||||
}
|
||||
}
|
||||
|
||||
bool validateAll() {
|
||||
@@ -376,13 +388,18 @@ class CreateRecipeCubit extends Cubit<CreateRecipeState> {
|
||||
await recipeRepository.deleteRecipe(slug);
|
||||
return true;
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
await reportFrom(e, s, this);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Future<List<GlossaryModel>> getGlossaryListByQuery(String query) async {
|
||||
return await glossaryRepository.getGlossaryListByQuery(query);
|
||||
try {
|
||||
return await glossaryRepository.getGlossaryListByQuery(query);
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
bool validateSteps() {
|
||||
|
||||
@@ -7,7 +7,6 @@ import 'package:eatvio_app/features/create_recipe/models/recipe_model.dart';
|
||||
import 'package:eatvio_app/features/create_recipe/models/recipe_tag_model.dart';
|
||||
import 'package:eatvio_app/features/create_recipe/models/step.dart';
|
||||
import 'package:eatvio_app/features/create_recipe/services/recipe_service.dart';
|
||||
import 'package:sentry_flutter/sentry_flutter.dart';
|
||||
import 'package:eatvio_app/features/create_recipe/models/product.dart';
|
||||
|
||||
class RecipeRepository {
|
||||
@@ -16,12 +15,8 @@ class RecipeRepository {
|
||||
RecipeRepository({required this.recipeService});
|
||||
|
||||
Future<Map<String, List<Product>>> inputProduct(String name) async {
|
||||
try {
|
||||
return await recipeService.getInputProduct(name);
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
}
|
||||
return await recipeService.getInputProduct(name);
|
||||
|
||||
}
|
||||
|
||||
Future<List> _buildStepsMap(List<Step?>? steps) async {
|
||||
@@ -110,67 +105,43 @@ class RecipeRepository {
|
||||
}
|
||||
|
||||
Future<void> publishRecipe(RecipeModel recipe, [bool update = false, String? slug]) async {
|
||||
try {
|
||||
final formData = await _buildPublishFormData(recipe);
|
||||
if (update) {
|
||||
await recipeService.updateRecipe(slug: slug!, formData: formData);
|
||||
} else {
|
||||
await recipeService.publishRecipe(formData: formData);
|
||||
}
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
final formData = await _buildPublishFormData(recipe);
|
||||
if (update) {
|
||||
await recipeService.updateRecipe(slug: slug!, formData: formData);
|
||||
} else {
|
||||
await recipeService.publishRecipe(formData: formData);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Future<void> saveAsDraft(RecipeModel recipe, [bool update = false, String? slug]) async {
|
||||
try {
|
||||
final formData = await _buildDraftFormData(recipe);
|
||||
log(formData.fields.toString());
|
||||
if (update) {
|
||||
await recipeService.updateRecipe(slug: slug!, formData: formData);
|
||||
} else {
|
||||
await recipeService.createDraftedRecipe(formData: formData);
|
||||
}
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
final formData = await _buildDraftFormData(recipe);
|
||||
log(formData.fields.toString());
|
||||
if (update) {
|
||||
await recipeService.updateRecipe(slug: slug!, formData: formData);
|
||||
} else {
|
||||
await recipeService.createDraftedRecipe(formData: formData);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Future<void> draftExistingRecipe(int id) async {
|
||||
try {
|
||||
await recipeService.draftRecipe(id: id);
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
}
|
||||
await recipeService.draftRecipe(id: id);
|
||||
|
||||
}
|
||||
|
||||
Future<RecipeModel> getRecipe(String recipeID) async {
|
||||
try {
|
||||
return await recipeService.getRecipe(recipeID);
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
}
|
||||
return await recipeService.getRecipe(recipeID);
|
||||
|
||||
}
|
||||
|
||||
Future<List<RecipeTag>> getRecipesTags() async {
|
||||
try {
|
||||
return (await recipeService.getTags()).data;
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
}
|
||||
return (await recipeService.getTags()).data;
|
||||
|
||||
}
|
||||
|
||||
Future<void> deleteRecipe(String slug) async {
|
||||
try {
|
||||
return await recipeService.deleteRecipe(slug: slug);
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
}
|
||||
return await recipeService.deleteRecipe(slug: slug);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -240,7 +240,7 @@ class _DevToolsScreenContentState extends State<DevToolsScreenContent> {
|
||||
} else {
|
||||
platform = 'ios';
|
||||
}
|
||||
await dio.post('/api/profile/notification/token/register', data: {'token': await FirebaseApi().getToken(), 'platform': platform});
|
||||
await dio.post('/api/profile/notification/token/register', data: {'token': await sl<FirebaseApi>().getToken(), 'platform': platform});
|
||||
showInfoToast('Токен добавлен');
|
||||
} catch (e) {
|
||||
showInfoToast('Не удалось добавть токен');
|
||||
@@ -253,7 +253,7 @@ class _DevToolsScreenContentState extends State<DevToolsScreenContent> {
|
||||
buttonStyle: const ButtonStyle(),
|
||||
onPressed: () async {
|
||||
try {
|
||||
final token = await FirebaseApi().getToken();
|
||||
final token = await sl<FirebaseApi>().getToken();
|
||||
if (token != null) {
|
||||
Clipboard.setData(ClipboardData(text: token));
|
||||
showInfoToast('Токен скопирован');
|
||||
@@ -278,7 +278,7 @@ class _DevToolsScreenContentState extends State<DevToolsScreenContent> {
|
||||
} else {
|
||||
platform = 'ios';
|
||||
}
|
||||
await dio.post('/api/profile/notification/token/unregister', data: {'token': await FirebaseApi().getToken(), 'platform': platform});
|
||||
await dio.post('/api/profile/notification/token/unregister', data: {'token': await sl<FirebaseApi>().getToken(), 'platform': platform});
|
||||
showInfoToast('Токен удалён');
|
||||
} catch (e) {
|
||||
showInfoToast('Не удалось удалить токен');
|
||||
|
||||
@@ -36,7 +36,6 @@ import 'package:eatvio_app/features/recipe/services/my_recipes_service.dart';
|
||||
import 'package:eatvio_app/features/registration/services/registration_service.dart';
|
||||
import 'package:eatvio_app/features/settings/services/settings_service.dart';
|
||||
import 'package:eatvio_app/core/env_config.dart';
|
||||
|
||||
class TestResult {
|
||||
final bool success;
|
||||
final String? error;
|
||||
@@ -57,7 +56,9 @@ class CreateRecipeTask implements TestCases {
|
||||
Future<TestResult> run({required String baseUrl}) async {
|
||||
try {
|
||||
final dio = sl<Dio>();
|
||||
final recipeRepository = RecipeRepository(recipeService: CreateRecipeService(dio, baseUrl: baseUrl));
|
||||
final recipeRepository = RecipeRepository(
|
||||
recipeService: CreateRecipeService(dio, baseUrl: baseUrl),
|
||||
);
|
||||
await recipeRepository.publishRecipe(
|
||||
const RecipeModel(
|
||||
title: 'Title',
|
||||
|
||||
@@ -3,6 +3,7 @@ import 'package:eatvio_app/features/diary/models/consultant_comment_model.dart';
|
||||
import 'package:eatvio_app/features/diary/presentation/bloc/consultant_comments_cubit/consultant_comments_state.dart';
|
||||
import 'package:eatvio_app/features/diary/repositories/diary_repository.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:eatvio_app/core/error_reporting/report_from.dart';
|
||||
|
||||
class ConsultantCommentsCubit extends Cubit<ConsultantCommentsState> {
|
||||
final DiaryRepository diaryRepository;
|
||||
@@ -74,6 +75,7 @@ class ConsultantCommentsCubit extends Cubit<ConsultantCommentsState> {
|
||||
}
|
||||
await diaryRepository.commentUserDay(diaryId: diaryId, commentModel: state.commentsModel);
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
log(e.toString(), stackTrace: st);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,8 +19,15 @@ 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/settings/repositories/service_repository.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:eatvio_app/core/error_reporting/report_from.dart';
|
||||
|
||||
class DiaryCubit extends Cubit<DiaryState> {
|
||||
static const NutritionModel _zeroNutritionModel = NutritionModel(energy: 0, proteins: 0, fats: 0, carbohydrates: 0);
|
||||
static const NutritionDataModel _fallbackNutrition = NutritionDataModel(
|
||||
dailyNutritionIntake: _zeroNutritionModel,
|
||||
dailyNutritionRecommendation: _zeroNutritionModel,
|
||||
);
|
||||
|
||||
late final DateTime today;
|
||||
late DateTime selectedDay;
|
||||
int selectedMeal = 1;
|
||||
@@ -102,6 +109,7 @@ class DiaryCubit extends Cubit<DiaryState> {
|
||||
emit(currentState);
|
||||
return false;
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
log(e.toString(), stackTrace: st);
|
||||
emit(DiaryState.error(errorMessage: e.toString()));
|
||||
return false;
|
||||
@@ -115,7 +123,8 @@ class DiaryCubit extends Cubit<DiaryState> {
|
||||
if (diaryEntity != null) {
|
||||
setDiary(diaryDay: diaryEntity, diaryId: diaryId);
|
||||
}
|
||||
} catch (e) {
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
log(e.toString());
|
||||
}
|
||||
}
|
||||
@@ -126,6 +135,7 @@ class DiaryCubit extends Cubit<DiaryState> {
|
||||
final diaryDay = await diaryRepository.getDiaryDayV2(day: selectedDay.toISO8601WithTimeZoneOffset());
|
||||
return diaryDay;
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
log(e.toString(), stackTrace: st);
|
||||
if (e is DioException) {
|
||||
if (e.response?.statusCode == 422) {
|
||||
@@ -152,8 +162,9 @@ class DiaryCubit extends Cubit<DiaryState> {
|
||||
return false;
|
||||
}
|
||||
emit(const DiaryState.loading());
|
||||
if (diaryDay.diet?.id != null && diaryDay.dayOfChosenDiet != null) {
|
||||
final diet = await dietRepository.getDiet((diaryDay.diet?.id)!);
|
||||
try {
|
||||
if (diaryDay.diet?.id != null && diaryDay.dayOfChosenDiet != null) {
|
||||
final diet = await dietRepository.getDiet((diaryDay.diet?.id)!);
|
||||
final meals = diet.dailySchedule[diaryDay.dayOfChosenDiet];
|
||||
final firstMealPortions = meals?[1]?.values.map((elem) {
|
||||
return PortionModel(
|
||||
@@ -221,9 +232,14 @@ class DiaryCubit extends Cubit<DiaryState> {
|
||||
selectedMeal: selectedMeal,
|
||||
),
|
||||
);
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
emit(DiaryState.error(errorMessage: e.toString()));
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
Future<void> setDiary({int? diaryId, required DiaryDayEntity diaryDay}) async {
|
||||
@@ -279,6 +295,7 @@ class DiaryCubit extends Cubit<DiaryState> {
|
||||
),
|
||||
);
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
log(e.toString(), stackTrace: st);
|
||||
emit(DiaryState.error(errorMessage: e.toString()));
|
||||
}
|
||||
@@ -290,13 +307,19 @@ class DiaryCubit extends Cubit<DiaryState> {
|
||||
await updateCurrentDiary();
|
||||
return true;
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
log(e.toString(), stackTrace: st);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Future<NutritionDataModel> getNutrition(int index) async {
|
||||
return (await diaryRepository.getNutritionData(index));
|
||||
try {
|
||||
return (await diaryRepository.getNutritionData(index));
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
return _fallbackNutrition;
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> addProductToMeal({
|
||||
@@ -308,15 +331,23 @@ class DiaryCubit extends Cubit<DiaryState> {
|
||||
int? productNutritionalValueId,
|
||||
}) async {
|
||||
emit((state as DiaryStateLoaded).copyWith(isLoadingAddingProductInMeal: true));
|
||||
await diaryRepository.addPortionToMeal(
|
||||
diaryId: diaryId,
|
||||
mealId: mealId,
|
||||
productName: productName,
|
||||
portion: portion,
|
||||
quantity: quantity,
|
||||
productNutritionalValueId: productNutritionalValueId,
|
||||
);
|
||||
await updateCurrentDiary();
|
||||
try {
|
||||
await diaryRepository.addPortionToMeal(
|
||||
diaryId: diaryId,
|
||||
mealId: mealId,
|
||||
productName: productName,
|
||||
portion: portion,
|
||||
quantity: quantity,
|
||||
productNutritionalValueId: productNutritionalValueId,
|
||||
);
|
||||
await updateCurrentDiary();
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
final s = state;
|
||||
if (s is DiaryStateLoaded) {
|
||||
emit(s.copyWith(isLoadingAddingProductInMeal: false));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> updateProductInMeal({
|
||||
@@ -329,62 +360,95 @@ class DiaryCubit extends Cubit<DiaryState> {
|
||||
int? productNutritionalValueId,
|
||||
required PortionState portionState,
|
||||
}) async {
|
||||
if (portionState == PortionState.filledDiet || portionState == PortionState.eatenFromDiet) {
|
||||
await diaryRepository.addPortionToMeal(
|
||||
diaryId: diaryId,
|
||||
mealId: mealId,
|
||||
productName: productName,
|
||||
portion: portion,
|
||||
quantity: quantity,
|
||||
productNutritionalValueId: productNutritionalValueId,
|
||||
);
|
||||
} else {
|
||||
await diaryRepository.updateProductInMeal(
|
||||
diaryId: diaryId,
|
||||
mealId: mealId,
|
||||
portionId: portionId,
|
||||
productName: productName,
|
||||
portion: portion,
|
||||
quantity: quantity,
|
||||
productNutritionalValueId: productNutritionalValueId,
|
||||
portionState: portionState,
|
||||
);
|
||||
try {
|
||||
if (portionState == PortionState.filledDiet || portionState == PortionState.eatenFromDiet) {
|
||||
await diaryRepository.addPortionToMeal(
|
||||
diaryId: diaryId,
|
||||
mealId: mealId,
|
||||
productName: productName,
|
||||
portion: portion,
|
||||
quantity: quantity,
|
||||
productNutritionalValueId: productNutritionalValueId,
|
||||
);
|
||||
} else {
|
||||
await diaryRepository.updateProductInMeal(
|
||||
diaryId: diaryId,
|
||||
mealId: mealId,
|
||||
portionId: portionId,
|
||||
productName: productName,
|
||||
portion: portion,
|
||||
quantity: quantity,
|
||||
productNutritionalValueId: productNutritionalValueId,
|
||||
portionState: portionState,
|
||||
);
|
||||
}
|
||||
await updateCurrentDiary();
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
}
|
||||
await updateCurrentDiary();
|
||||
}
|
||||
|
||||
Future<void> markEaten({required int diaryId, required int mealId, required int portionId}) async {
|
||||
await diaryRepository.markEaten(diaryId: diaryId, mealId: mealId, portionId: portionId);
|
||||
await updateCurrentDiary();
|
||||
try {
|
||||
await diaryRepository.markEaten(diaryId: diaryId, mealId: mealId, portionId: portionId);
|
||||
await updateCurrentDiary();
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> unmarkEaten({required int diaryId, required int mealId, required int portionId}) async {
|
||||
await diaryRepository.unmarkEaten(diaryId: diaryId, mealId: mealId, portionId: portionId);
|
||||
await updateCurrentDiary();
|
||||
try {
|
||||
await diaryRepository.unmarkEaten(diaryId: diaryId, mealId: mealId, portionId: portionId);
|
||||
await updateCurrentDiary();
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> restore({required int diaryId, required int mealId, required int portionId}) async {
|
||||
await diaryRepository.restore(diaryId: diaryId, mealId: mealId, portionId: portionId);
|
||||
await updateCurrentDiary();
|
||||
try {
|
||||
await diaryRepository.restore(diaryId: diaryId, mealId: mealId, portionId: portionId);
|
||||
await updateCurrentDiary();
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> deleteProductFromMeal({required int diaryId, required int mealId, required int portionId}) async {
|
||||
await diaryRepository.deleteProductFromMeal(diaryId: diaryId, mealId: mealId, portionId: portionId);
|
||||
await updateCurrentDiary();
|
||||
try {
|
||||
await diaryRepository.deleteProductFromMeal(diaryId: diaryId, mealId: mealId, portionId: portionId);
|
||||
await updateCurrentDiary();
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
}
|
||||
}
|
||||
|
||||
Future<List<GlossaryModel>> getGlossaryListByQuery(String query) async {
|
||||
return await glossaryRepository.getGlossaryListByQuery(query);
|
||||
try {
|
||||
return await glossaryRepository.getGlossaryListByQuery(query);
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> uploadPhotos({required List<File> files, required int diaryId}) async {
|
||||
await diaryRepository.uploadPhotos(files: await ImageCompressUtility.compressFilesList(files), diaryId: diaryId, mealId: selectedMeal);
|
||||
await updateCurrentDiary();
|
||||
try {
|
||||
await diaryRepository.uploadPhotos(files: await ImageCompressUtility.compressFilesList(files), diaryId: diaryId, mealId: selectedMeal);
|
||||
await updateCurrentDiary();
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> deletePhoto({required DiaryPhotoModel photo, required int diaryId}) async {
|
||||
await diaryRepository.deletePhoto(photo: photo, diaryId: diaryId, mealId: selectedMeal);
|
||||
await updateCurrentDiary();
|
||||
try {
|
||||
await diaryRepository.deletePhoto(photo: photo, diaryId: diaryId, mealId: selectedMeal);
|
||||
await updateCurrentDiary();
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
}
|
||||
}
|
||||
|
||||
Future<GlossaryModerationModel?> sendProductToModeration({
|
||||
@@ -397,34 +461,55 @@ class DiaryCubit extends Cubit<DiaryState> {
|
||||
try {
|
||||
return await diaryRepository.sendProductToModeration(name: name, energy: energy, proteins: proteins, fats: fats, carbohydrates: carbohydrates);
|
||||
} catch (e, stackTrace) {
|
||||
await reportFrom(e, stackTrace, this);
|
||||
log(e.toString(), stackTrace: stackTrace);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
Future<void> fillTime({required int diaryId, required String time}) async {
|
||||
await diaryRepository.fillTime(diaryId: diaryId, mealId: selectedMeal, time: time);
|
||||
await updateCurrentDiary();
|
||||
try {
|
||||
await diaryRepository.fillTime(diaryId: diaryId, mealId: selectedMeal, time: time);
|
||||
await updateCurrentDiary();
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> fillWakeup({required int diaryId, required String time}) async {
|
||||
await diaryRepository.fillWakeup(diaryId: diaryId, time: time);
|
||||
await updateCurrentDiary();
|
||||
try {
|
||||
await diaryRepository.fillWakeup(diaryId: diaryId, time: time);
|
||||
await updateCurrentDiary();
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> fillRetire({required int diaryId, required String time}) async {
|
||||
await diaryRepository.fillRetire(diaryId: diaryId, time: time);
|
||||
await updateCurrentDiary();
|
||||
try {
|
||||
await diaryRepository.fillRetire(diaryId: diaryId, time: time);
|
||||
await updateCurrentDiary();
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> fillSatiety({required int diaryId, required int satiety}) async {
|
||||
await diaryRepository.fillSatiety(diaryId: diaryId, mealId: selectedMeal, satiety: satiety);
|
||||
await updateCurrentDiary();
|
||||
try {
|
||||
await diaryRepository.fillSatiety(diaryId: diaryId, mealId: selectedMeal, satiety: satiety);
|
||||
await updateCurrentDiary();
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> fillMood({required int diaryId, required int mood}) async {
|
||||
await diaryRepository.fillMood(diaryId: diaryId, mealId: selectedMeal, mood: mood);
|
||||
await updateCurrentDiary();
|
||||
try {
|
||||
await diaryRepository.fillMood(diaryId: diaryId, mealId: selectedMeal, mood: mood);
|
||||
await updateCurrentDiary();
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
}
|
||||
}
|
||||
|
||||
void fillComment(String comment) {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import 'dart:async';
|
||||
import 'dart:io';
|
||||
import 'package:dio/dio.dart';
|
||||
|
||||
import 'package:collection/collection.dart';
|
||||
import 'package:eatvio_app/features/diary/models/consultant_comment_model.dart';
|
||||
import 'package:eatvio_app/features/diary/models/consultant_review_model.dart';
|
||||
import 'package:eatvio_app/features/diary/models/create_day_model.dart';
|
||||
@@ -10,7 +11,6 @@ import 'package:eatvio_app/features/diary/models/nutrition_model.dart';
|
||||
import 'package:eatvio_app/features/diary/models/product_moderation_model.dart';
|
||||
import 'package:eatvio_app/features/diary/services/diary_service.dart';
|
||||
import 'package:eatvio_app/features/glossary/models/glossary_model.dart';
|
||||
import 'package:sentry_flutter/sentry_flutter.dart';
|
||||
|
||||
class DiaryRepository {
|
||||
final DiaryService diaryService;
|
||||
@@ -20,134 +20,82 @@ class DiaryRepository {
|
||||
|
||||
DiaryRepository({required this.diaryService});
|
||||
|
||||
Future<DiaryDayModel> getDiaryByDate(String date) async {
|
||||
try {
|
||||
Set<int> ids = {};
|
||||
final diaryDays = await getDiaryIndexByDate(date);
|
||||
if (diaryDays.isEmpty) {
|
||||
throw Exception('No diary entry found for $date');
|
||||
}
|
||||
final DiaryDayModel diaryDay = diaryDays.last;
|
||||
for (var meal in diaryDay.meals) {
|
||||
for (var portion in meal.portions) {
|
||||
if (portion.productNutritionalValueId != null) {
|
||||
ids.add(portion.productNutritionalValueId!);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (ids.isNotEmpty) {
|
||||
final glossary = await getGlossariesIndex(ids: ids.toList());
|
||||
final List<MealModel> updatedMeals = List.from(diaryDay.meals);
|
||||
for (var mealIndex = 0; mealIndex < updatedMeals.length; mealIndex++) {
|
||||
final meal = updatedMeals[mealIndex];
|
||||
final updatedPortions = meal.portions.map((portion) {
|
||||
if (portion.productNutritionalValueId != null) {
|
||||
try {
|
||||
final glossaryItem = glossary.glossariesList.firstWhere((g) => g.id == portion.productNutritionalValueId);
|
||||
return portion.copyWith(
|
||||
productCaloriesInfo: ProductCaloriesInfoModel(
|
||||
id: glossaryItem.id,
|
||||
productName: glossaryItem.name,
|
||||
calories: glossaryItem.energyOn100Gr,
|
||||
proteins: glossaryItem.proteinsOn100Gr,
|
||||
fats: glossaryItem.fatsOn100Gr,
|
||||
carbohydrates: glossaryItem.carbohydratesOn100Gr,
|
||||
energyOnPortion: glossaryItem.energyOnPortion,
|
||||
proteinsOnPortion: glossaryItem.proteinsOnPortion,
|
||||
fatsOnPortion: glossaryItem.fatsOnPortion,
|
||||
carbohydratesOnPortion: glossaryItem.carbohydratesOnPortion,
|
||||
),
|
||||
);
|
||||
} catch (e) {
|
||||
return portion;
|
||||
}
|
||||
}
|
||||
return portion;
|
||||
}).toList();
|
||||
PortionModel _portionWithGlossary(PortionModel portion, List<GlossaryModel> glossaries) {
|
||||
final id = portion.productNutritionalValueId;
|
||||
if (id == null) return portion;
|
||||
final glossaryItem = glossaries.firstWhereOrNull((g) => g.id == id);
|
||||
if (glossaryItem == null) return portion;
|
||||
return portion.copyWith(
|
||||
productCaloriesInfo: ProductCaloriesInfoModel(
|
||||
id: glossaryItem.id,
|
||||
productName: glossaryItem.name,
|
||||
calories: glossaryItem.energyOn100Gr,
|
||||
proteins: glossaryItem.proteinsOn100Gr,
|
||||
fats: glossaryItem.fatsOn100Gr,
|
||||
carbohydrates: glossaryItem.carbohydratesOn100Gr,
|
||||
energyOnPortion: glossaryItem.energyOnPortion,
|
||||
proteinsOnPortion: glossaryItem.proteinsOnPortion,
|
||||
fatsOnPortion: glossaryItem.fatsOnPortion,
|
||||
carbohydratesOnPortion: glossaryItem.carbohydratesOnPortion,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
updatedMeals[mealIndex] = meal.copyWith(portions: updatedPortions);
|
||||
}
|
||||
final updatedDiaryDay = diaryDay.copyWith(meals: updatedMeals);
|
||||
return updatedDiaryDay;
|
||||
}
|
||||
return diaryDay;
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
Future<DiaryDayModel> getDiaryByDate(String date) async {
|
||||
final ids = <int>{};
|
||||
final diaryDays = await getDiaryIndexByDate(date);
|
||||
if (diaryDays.isEmpty) {
|
||||
throw Exception('No diary entry found for $date');
|
||||
}
|
||||
final DiaryDayModel diaryDay = diaryDays.last;
|
||||
for (var meal in diaryDay.meals) {
|
||||
for (var portion in meal.portions) {
|
||||
if (portion.productNutritionalValueId != null) {
|
||||
ids.add(portion.productNutritionalValueId!);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (ids.isEmpty) {
|
||||
return diaryDay;
|
||||
}
|
||||
final glossary = await getGlossariesIndex(ids: ids.toList());
|
||||
final glossaries = glossary.glossariesList;
|
||||
final updatedMeals = diaryDay.meals.map((meal) {
|
||||
final updatedPortions = meal.portions.map((p) => _portionWithGlossary(p, glossaries)).toList();
|
||||
return meal.copyWith(portions: updatedPortions);
|
||||
}).toList();
|
||||
return diaryDay.copyWith(meals: updatedMeals);
|
||||
}
|
||||
|
||||
Future<List<DiaryDayModel>> getDiaryIndexByDate(String date) async {
|
||||
try {
|
||||
return (await diaryService.getDiaryIndexByDate(date: date));
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
}
|
||||
return diaryService.getDiaryIndexByDate(date: date);
|
||||
}
|
||||
|
||||
Future<DiaryDayModel> getDiaryDay(int diaryId) async {
|
||||
try {
|
||||
// Align with getDiaryByDate: enrich portions with glossary nutritional info
|
||||
final diaryWrapper = await diaryService.getDiaryDay(diary: diaryId);
|
||||
final DiaryDayModel diaryDay = diaryWrapper.diary;
|
||||
Set<int> ids = {};
|
||||
for (var meal in diaryDay.meals) {
|
||||
for (var portion in meal.portions) {
|
||||
if (portion.productNutritionalValueId != null) {
|
||||
ids.add(portion.productNutritionalValueId!);
|
||||
}
|
||||
final diaryWrapper = await diaryService.getDiaryDay(diary: diaryId);
|
||||
final DiaryDayModel diaryDay = diaryWrapper.diary;
|
||||
final ids = <int>{};
|
||||
for (var meal in diaryDay.meals) {
|
||||
for (var portion in meal.portions) {
|
||||
if (portion.productNutritionalValueId != null) {
|
||||
ids.add(portion.productNutritionalValueId!);
|
||||
}
|
||||
}
|
||||
if (ids.isNotEmpty) {
|
||||
final glossary = await getGlossariesIndex(ids: ids.toList());
|
||||
final List<MealModel> updatedMeals = List.from(diaryDay.meals);
|
||||
for (var mealIndex = 0; mealIndex < updatedMeals.length; mealIndex++) {
|
||||
final meal = updatedMeals[mealIndex];
|
||||
final updatedPortions = meal.portions.map((portion) {
|
||||
if (portion.productNutritionalValueId != null) {
|
||||
try {
|
||||
final glossaryItem = glossary.glossariesList.firstWhere((g) => g.id == portion.productNutritionalValueId);
|
||||
return portion.copyWith(
|
||||
productCaloriesInfo: ProductCaloriesInfoModel(
|
||||
id: glossaryItem.id,
|
||||
productName: glossaryItem.name,
|
||||
calories: glossaryItem.energyOn100Gr,
|
||||
proteins: glossaryItem.proteinsOn100Gr,
|
||||
fats: glossaryItem.fatsOn100Gr,
|
||||
carbohydrates: glossaryItem.carbohydratesOn100Gr,
|
||||
energyOnPortion: glossaryItem.energyOnPortion,
|
||||
proteinsOnPortion: glossaryItem.proteinsOnPortion,
|
||||
fatsOnPortion: glossaryItem.fatsOnPortion,
|
||||
carbohydratesOnPortion: glossaryItem.carbohydratesOnPortion,
|
||||
),
|
||||
);
|
||||
} catch (e) {
|
||||
return portion;
|
||||
}
|
||||
}
|
||||
return portion;
|
||||
}).toList();
|
||||
|
||||
updatedMeals[mealIndex] = meal.copyWith(portions: updatedPortions);
|
||||
}
|
||||
final updatedDiaryDay = diaryDay.copyWith(meals: updatedMeals);
|
||||
return updatedDiaryDay;
|
||||
}
|
||||
return diaryDay;
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
}
|
||||
if (ids.isEmpty) {
|
||||
return diaryDay;
|
||||
}
|
||||
final glossary = await getGlossariesIndex(ids: ids.toList());
|
||||
final glossaries = glossary.glossariesList;
|
||||
final updatedMeals = diaryDay.meals.map((meal) {
|
||||
final updatedPortions = meal.portions.map((p) => _portionWithGlossary(p, glossaries)).toList();
|
||||
return meal.copyWith(portions: updatedPortions);
|
||||
}).toList();
|
||||
return diaryDay.copyWith(meals: updatedMeals);
|
||||
}
|
||||
|
||||
Future<NutritionDataModel> getNutritionData(int index) async {
|
||||
try {
|
||||
return await diaryService.getNutrition(diary: index);
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
}
|
||||
return diaryService.getNutrition(diary: index);
|
||||
}
|
||||
|
||||
Future<void> addPortionToMeal({
|
||||
@@ -158,19 +106,14 @@ class DiaryRepository {
|
||||
required int quantity,
|
||||
int? productNutritionalValueId,
|
||||
}) async {
|
||||
try {
|
||||
return await diaryService.addProductToMeal(
|
||||
diary: diaryId,
|
||||
typeNo: mealId,
|
||||
productName: productName,
|
||||
portion: portion,
|
||||
quantity: quantity,
|
||||
productNutritionalValueId: productNutritionalValueId,
|
||||
);
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
}
|
||||
return diaryService.addProductToMeal(
|
||||
diary: diaryId,
|
||||
typeNo: mealId,
|
||||
productName: productName,
|
||||
portion: portion,
|
||||
quantity: quantity,
|
||||
productNutritionalValueId: productNutritionalValueId,
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> updateProductInMeal({
|
||||
@@ -183,83 +126,43 @@ class DiaryRepository {
|
||||
int? productNutritionalValueId,
|
||||
required PortionState portionState,
|
||||
}) async {
|
||||
try {
|
||||
Map<String, Object?> data = ProductInMeal(productName: productName, portion: portion, quantity: quantity).toJson();
|
||||
if (productNutritionalValueId != null) data['product_nutritional_value_id'] = productNutritionalValueId;
|
||||
data['state'] = portionState.name;
|
||||
return await diaryService.updateProductInMeal(diary: diaryId, typeNo: mealId, portionModel: portionId, productInMeal: data);
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
}
|
||||
final data = ProductInMeal(productName: productName, portion: portion, quantity: quantity).toJson();
|
||||
if (productNutritionalValueId != null) data['product_nutritional_value_id'] = productNutritionalValueId;
|
||||
data['state'] = portionState.name;
|
||||
return diaryService.updateProductInMeal(diary: diaryId, typeNo: mealId, portionModel: portionId, productInMeal: data);
|
||||
}
|
||||
|
||||
Future<void> markEaten({required int diaryId, required int mealId, required int portionId}) async {
|
||||
try {
|
||||
return await diaryService.markEaten(diary: diaryId, typeNo: mealId, portionModel: portionId);
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
}
|
||||
return diaryService.markEaten(diary: diaryId, typeNo: mealId, portionModel: portionId);
|
||||
}
|
||||
|
||||
Future<void> unmarkEaten({required int diaryId, required int mealId, required int portionId}) async {
|
||||
try {
|
||||
return await diaryService.unmarkEaten(diary: diaryId, typeNo: mealId, portionModel: portionId);
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
}
|
||||
return diaryService.unmarkEaten(diary: diaryId, typeNo: mealId, portionModel: portionId);
|
||||
}
|
||||
|
||||
Future<void> restore({required int diaryId, required int mealId, required int portionId}) async {
|
||||
try {
|
||||
return await diaryService.restore(diary: diaryId, typeNo: mealId, portionModel: portionId);
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
}
|
||||
return diaryService.restore(diary: diaryId, typeNo: mealId, portionModel: portionId);
|
||||
}
|
||||
|
||||
Future<void> deleteProductFromMeal({required int diaryId, required int mealId, required int portionId}) async {
|
||||
try {
|
||||
return await diaryService.deleteProductFromMeal(diary: diaryId, typeNo: mealId, portionModel: portionId);
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
}
|
||||
return diaryService.deleteProductFromMeal(diary: diaryId, typeNo: mealId, portionModel: portionId);
|
||||
}
|
||||
|
||||
Future<void> uploadPhotos({required int diaryId, required int mealId, required List<File> files}) async {
|
||||
try {
|
||||
for (int i = 0; i < files.length; i++) {
|
||||
await diaryService.uploadPhotoOfMeal(diary: diaryId, typeNo: mealId, photo: files[i]);
|
||||
}
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
for (var i = 0; i < files.length; i++) {
|
||||
await diaryService.uploadPhotoOfMeal(diary: diaryId, typeNo: mealId, photo: files[i]);
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> deletePhoto({required int diaryId, required int mealId, required DiaryPhotoModel photo}) async {
|
||||
try {
|
||||
await diaryService.deletePhotoOfMeal(diaryId: diaryId, typeNo: mealId, userAttachment: photo.id);
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
}
|
||||
await diaryService.deletePhotoOfMeal(diaryId: diaryId, typeNo: mealId, userAttachment: photo.id);
|
||||
}
|
||||
|
||||
Future<void> finishDiaryDay({required int diaryId, required String wakeUp, required String retire, String? comment}) async {
|
||||
try {
|
||||
return await diaryService.finishDiaryDay(
|
||||
diary: diaryId,
|
||||
finishDiaryDayModel: FinishDiaryDayModel(wakeUp: wakeUp, retire: retire, comment: comment),
|
||||
);
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
}
|
||||
return diaryService.finishDiaryDay(
|
||||
diary: diaryId,
|
||||
finishDiaryDayModel: FinishDiaryDayModel(wakeUp: wakeUp, retire: retire, comment: comment),
|
||||
);
|
||||
}
|
||||
|
||||
Future<GlossaryModerationModel> sendProductToModeration({
|
||||
@@ -269,129 +172,66 @@ class DiaryRepository {
|
||||
required double fats,
|
||||
required double carbohydrates,
|
||||
}) async {
|
||||
try {
|
||||
return await diaryService.sendProductToModeration(
|
||||
data: ProductModerationModel(name: name, energy: energy, proteins: proteins, fats: fats, carbohydrates: carbohydrates).toJson(),
|
||||
);
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
}
|
||||
return diaryService.sendProductToModeration(
|
||||
data: ProductModerationModel(name: name, energy: energy, proteins: proteins, fats: fats, carbohydrates: carbohydrates).toJson(),
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> fillSatiety({required int diaryId, required int mealId, required int satiety}) async {
|
||||
try {
|
||||
return await diaryService.fillSatiety(diary: diaryId, typeNo: mealId, satiety: satiety);
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
}
|
||||
return diaryService.fillSatiety(diary: diaryId, typeNo: mealId, satiety: satiety);
|
||||
}
|
||||
|
||||
Future<void> fillMood({required int diaryId, required int mealId, required int mood}) async {
|
||||
try {
|
||||
return await diaryService.fillMood(diary: diaryId, typeNo: mealId, mood: mood);
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
}
|
||||
return diaryService.fillMood(diary: diaryId, typeNo: mealId, mood: mood);
|
||||
}
|
||||
|
||||
Future<void> fillTime({required int diaryId, required int mealId, required String time}) async {
|
||||
try {
|
||||
return await diaryService.fillTime(diary: diaryId, typeNo: mealId, time: time);
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
}
|
||||
return diaryService.fillTime(diary: diaryId, typeNo: mealId, time: time);
|
||||
}
|
||||
|
||||
Future<void> fillWakeup({required int diaryId, required String time}) async {
|
||||
try {
|
||||
return await diaryService.fillWakeup(diary: diaryId, wakeUp: time);
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
}
|
||||
return diaryService.fillWakeup(diary: diaryId, wakeUp: time);
|
||||
}
|
||||
|
||||
Future<void> fillRetire({required int diaryId, required String time}) async {
|
||||
try {
|
||||
return await diaryService.fillRetire(diary: diaryId, retire: time);
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
}
|
||||
return diaryService.fillRetire(diary: diaryId, retire: time);
|
||||
}
|
||||
|
||||
Future<void> commentUserDay({required int diaryId, required ConsultantCommentModel commentModel}) async {
|
||||
try {
|
||||
await diaryService.commentUserDay(id: diaryId, body: commentModel);
|
||||
_diaryForceFetchController.add('force');
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
}
|
||||
await diaryService.commentUserDay(id: diaryId, body: commentModel);
|
||||
_diaryForceFetchController.add('force');
|
||||
}
|
||||
|
||||
Future<ConsultantReviewModel> getDiaryComments({required int planId, required int diaryId}) async {
|
||||
try {
|
||||
return await diaryService.getDiaryComments(planId: planId, diaryId: diaryId);
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
}
|
||||
return diaryService.getDiaryComments(planId: planId, diaryId: diaryId);
|
||||
}
|
||||
|
||||
Future<void> viewCommentOfDiaryDayByConsultant({required int diaryId}) async {
|
||||
try {
|
||||
await diaryService.viewCommentOfDiaryDayByConsultant(diaryId: diaryId);
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
}
|
||||
await diaryService.viewCommentOfDiaryDayByConsultant(diaryId: diaryId);
|
||||
}
|
||||
|
||||
Future<GlossaryPaginationModel> getGlossariesIndex({required List<int> ids}) async {
|
||||
Map<String, dynamic> filters = {};
|
||||
final filters = <String, dynamic>{};
|
||||
if (ids.isNotEmpty) {
|
||||
for (int i = 0; i < ids.length; i++) {
|
||||
for (var i = 0; i < ids.length; i++) {
|
||||
filters['filters[id][\$in][$i]'] = ids[i];
|
||||
}
|
||||
}
|
||||
try {
|
||||
return await diaryService.getGlossariesIndex(filters: filters);
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
}
|
||||
return diaryService.getGlossariesIndex(filters: filters);
|
||||
}
|
||||
|
||||
Future<DiaryDayModel> getDiaryDayV2({required String day}) async {
|
||||
try {
|
||||
final diaryDay = await diaryService.getDiaryDayV2(day: day);
|
||||
return setCPFCToDiary(diaryDay);
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
}
|
||||
final diaryDay = await diaryService.getDiaryDayV2(day: day);
|
||||
return setCPFCToDiary(diaryDay);
|
||||
}
|
||||
|
||||
Future<void> createDiaryDay({required String day}) async {
|
||||
try {
|
||||
await diaryService.createDay(body: CreateDayModel(day: day));
|
||||
await getDiaryByDate(day);
|
||||
} catch (e, s) {
|
||||
if (e is DioException && e.response?.statusCode == 422) {
|
||||
} else {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
}
|
||||
rethrow;
|
||||
}
|
||||
await diaryService.createDay(body: CreateDayModel(day: day));
|
||||
await getDiaryByDate(day);
|
||||
}
|
||||
|
||||
Future<DiaryDayModel> setCPFCToDiary(DiaryDayModel diaryDay) async {
|
||||
Set<int> ids = {};
|
||||
final ids = <int>{};
|
||||
for (var meal in diaryDay.meals) {
|
||||
for (var portion in meal.portions) {
|
||||
if (portion.productNutritionalValueId != null) {
|
||||
@@ -399,41 +239,15 @@ class DiaryRepository {
|
||||
}
|
||||
}
|
||||
}
|
||||
if (ids.isNotEmpty) {
|
||||
final glossary = await getGlossariesIndex(ids: ids.toList());
|
||||
final List<MealModel> updatedMeals = List.from(diaryDay.meals);
|
||||
for (var mealIndex = 0; mealIndex < updatedMeals.length; mealIndex++) {
|
||||
final meal = updatedMeals[mealIndex];
|
||||
final updatedPortions = meal.portions.map((portion) {
|
||||
if (portion.productNutritionalValueId != null) {
|
||||
try {
|
||||
final glossaryItem = glossary.glossariesList.firstWhere((g) => g.id == portion.productNutritionalValueId);
|
||||
return portion.copyWith(
|
||||
productCaloriesInfo: ProductCaloriesInfoModel(
|
||||
id: glossaryItem.id,
|
||||
productName: glossaryItem.name,
|
||||
calories: glossaryItem.energyOn100Gr,
|
||||
proteins: glossaryItem.proteinsOn100Gr,
|
||||
fats: glossaryItem.fatsOn100Gr,
|
||||
carbohydrates: glossaryItem.carbohydratesOn100Gr,
|
||||
energyOnPortion: glossaryItem.energyOnPortion,
|
||||
proteinsOnPortion: glossaryItem.proteinsOnPortion,
|
||||
fatsOnPortion: glossaryItem.fatsOnPortion,
|
||||
carbohydratesOnPortion: glossaryItem.carbohydratesOnPortion,
|
||||
),
|
||||
);
|
||||
} catch (e) {
|
||||
return portion;
|
||||
}
|
||||
}
|
||||
return portion;
|
||||
}).toList();
|
||||
|
||||
updatedMeals[mealIndex] = meal.copyWith(portions: updatedPortions);
|
||||
}
|
||||
final updatedDiaryDay = diaryDay.copyWith(meals: updatedMeals);
|
||||
return updatedDiaryDay;
|
||||
if (ids.isEmpty) {
|
||||
return diaryDay;
|
||||
}
|
||||
return diaryDay;
|
||||
final glossary = await getGlossariesIndex(ids: ids.toList());
|
||||
final glossaries = glossary.glossariesList;
|
||||
final updatedMeals = diaryDay.meals.map((meal) {
|
||||
final updatedPortions = meal.portions.map((p) => _portionWithGlossary(p, glossaries)).toList();
|
||||
return meal.copyWith(portions: updatedPortions);
|
||||
}).toList();
|
||||
return diaryDay.copyWith(meals: updatedMeals);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ import 'package:eatvio_app/features/diets/presentation/cubit/about_diet_state.da
|
||||
import 'package:eatvio_app/features/feed/models/diets_pagination_model.dart';
|
||||
import 'package:eatvio_app/features/profile/repositories/profile_repository.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:eatvio_app/core/error_reporting/report_from.dart';
|
||||
|
||||
class AboutDietCubit extends Cubit<AboutDietState> {
|
||||
AboutDietCubit({required this.dietsRepository, required this.profileRepository}) : super(const AboutDietState.initial());
|
||||
@@ -31,7 +32,8 @@ class AboutDietCubit extends Cubit<AboutDietState> {
|
||||
dietsRepository.emitCommentsStateToFeed(CommentsState(index: index, totalComments: diet.totalComments));
|
||||
}
|
||||
emit(AboutDietState.loaded(diet: diet, isStarted: isCurrentDietStarted, hasStartedDiet: hasStartedDiet));
|
||||
} catch (e) {
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
log(e.toString());
|
||||
emit(AboutDietState.error(message: e.toString()));
|
||||
}
|
||||
@@ -62,7 +64,8 @@ class AboutDietCubit extends Cubit<AboutDietState> {
|
||||
}
|
||||
_selectedIndexes = List.generate(diet.dailySchedule.length, (index) => 0);
|
||||
emit(AboutDietState.loaded(diet: diet, isStarted: isCurrentDietStarted, hasStartedDiet: hasStartedDiet, selectedIndexes: _selectedIndexes));
|
||||
} catch (e) {
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
log(e.toString());
|
||||
emit(AboutDietState.error(message: e.toString()));
|
||||
}
|
||||
@@ -90,7 +93,8 @@ class AboutDietCubit extends Cubit<AboutDietState> {
|
||||
EasyDebounce.debounce('like_diet', const Duration(seconds: 1), () async {
|
||||
try {
|
||||
await dietsRepository.likeDiet(id);
|
||||
} catch (e) {
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
log(e.toString());
|
||||
if (dietIndexInFeed != null) {
|
||||
dietsRepository.emitLikesStateToFeed(LikesState(wasLikedByMe: currentDiet.wasLikedByMe, totalLikes: currentDiet.totalLikes, index: dietIndexInFeed));
|
||||
@@ -114,7 +118,8 @@ class AboutDietCubit extends Cubit<AboutDietState> {
|
||||
EasyDebounce.debounce('add_or_remove_diet_to_favorites', const Duration(seconds: 1), () async {
|
||||
try {
|
||||
await dietsRepository.addToFavorite(id);
|
||||
} catch (e) {
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
log(e.toString());
|
||||
showErrorToast('Произошла ошибка. Попробуйте ещё раз через некоторое время');
|
||||
if (dietIndex != null) {
|
||||
@@ -139,7 +144,8 @@ class AboutDietCubit extends Cubit<AboutDietState> {
|
||||
EasyDebounce.debounce('add_or_remove_diet_to_favorites', const Duration(seconds: 1), () async {
|
||||
try {
|
||||
await dietsRepository.removeFromFavorite(id);
|
||||
} catch (e) {
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
log(e.toString());
|
||||
showErrorToast('Произошла ошибка. Попробуйте ещё раз через некоторое время');
|
||||
if (dietIndex != null) {
|
||||
@@ -159,6 +165,7 @@ class AboutDietCubit extends Cubit<AboutDietState> {
|
||||
await dietsRepository.startDiet(id, stringDate);
|
||||
return true;
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
log(e.toString(), stackTrace: st);
|
||||
return false;
|
||||
}
|
||||
@@ -170,10 +177,12 @@ class AboutDietCubit extends Cubit<AboutDietState> {
|
||||
final id = (state as DietStateLoaded).diet.id;
|
||||
await dietsRepository.cancelDiet(id);
|
||||
return true;
|
||||
} on DioException catch (e) {
|
||||
} on DioException catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
log(e.toString());
|
||||
return false;
|
||||
} catch (e) {
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
log(e.toString());
|
||||
return false;
|
||||
}
|
||||
@@ -194,7 +203,8 @@ class AboutDietCubit extends Cubit<AboutDietState> {
|
||||
Future<Diet?> getDietBySlug(String slug) async {
|
||||
try {
|
||||
return await dietsRepository.getDietBySlug(slug);
|
||||
} catch (e) {
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
log(e.toString());
|
||||
}
|
||||
return null;
|
||||
|
||||
@@ -4,7 +4,6 @@ import 'package:eatvio_app/features/diets/models/diet_likes_model.dart';
|
||||
import 'package:eatvio_app/features/diets/services/diet_service.dart';
|
||||
import 'package:eatvio_app/features/feed/models/diets_pagination_model.dart';
|
||||
import 'package:equatable/equatable.dart';
|
||||
import 'package:sentry_flutter/sentry_flutter.dart';
|
||||
|
||||
class DietRepository {
|
||||
DietRepository({required this.dietsService});
|
||||
@@ -18,76 +17,44 @@ class DietRepository {
|
||||
Stream get dietCommentsState => _dietCommentsStateStreamController.stream;
|
||||
|
||||
Future<DietLikesModel> likeDiet(int id) async {
|
||||
try {
|
||||
return await dietsService.likeDiet(id: id);
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
}
|
||||
return await dietsService.likeDiet(id: id);
|
||||
|
||||
}
|
||||
|
||||
Future<Diet> getDiet(int id) async {
|
||||
try {
|
||||
final diet = await dietsService.getDiet(id: id);
|
||||
return diet;
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
}
|
||||
final diet = await dietsService.getDiet(id: id);
|
||||
return diet;
|
||||
|
||||
}
|
||||
|
||||
Future<Diet> getDietBySlug(String slug) async {
|
||||
try {
|
||||
final diet = await dietsService.getDietBySlug(slug: slug);
|
||||
return diet;
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
}
|
||||
final diet = await dietsService.getDietBySlug(slug: slug);
|
||||
return diet;
|
||||
|
||||
}
|
||||
|
||||
Future<Diet> addToFavorite(int id) async {
|
||||
try {
|
||||
return await dietsService.addToFavorite(id: id);
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
}
|
||||
return await dietsService.addToFavorite(id: id);
|
||||
|
||||
}
|
||||
|
||||
Future<Diet> removeFromFavorite(int id) async {
|
||||
try {
|
||||
return await dietsService.removeFromFavorite(id: id);
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
}
|
||||
return await dietsService.removeFromFavorite(id: id);
|
||||
|
||||
}
|
||||
|
||||
Future<void> startDiet(int id, String date) async {
|
||||
try {
|
||||
return await dietsService.startDiet(id: id, body: {'date': date});
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
}
|
||||
return await dietsService.startDiet(id: id, body: {'date': date});
|
||||
|
||||
}
|
||||
|
||||
Future<void> cancelDiet(int id) async{
|
||||
try {
|
||||
return await dietsService.cancelDiet(id: id);
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
}
|
||||
return await dietsService.cancelDiet(id: id);
|
||||
|
||||
}
|
||||
|
||||
Future<void> deleteDiet(int id) async {
|
||||
try {
|
||||
return await dietsService.deleteDiet(id: id);
|
||||
} catch (e) {
|
||||
rethrow;
|
||||
}
|
||||
return dietsService.deleteDiet(id: id);
|
||||
}
|
||||
|
||||
void emitLikesStateToFeed(LikesState state) => _dietLikeStateStreamController.add(state);
|
||||
|
||||
@@ -3,6 +3,7 @@ import 'dart:developer';
|
||||
import 'package:eatvio_app/features/feed/presentation/bloc/consultants_cubit/consultants_state.dart';
|
||||
import 'package:eatvio_app/features/feed/repositories/feed_repository.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:eatvio_app/core/error_reporting/report_from.dart';
|
||||
|
||||
class ConsultantsCubit extends Cubit<ConsultantsState> {
|
||||
final FeedRepository feedRepository;
|
||||
@@ -21,6 +22,7 @@ class ConsultantsCubit extends Cubit<ConsultantsState> {
|
||||
),
|
||||
);
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
log(e.toString(), stackTrace: st);
|
||||
emit(ConsultantsState.error(errorMessage: e.toString()));
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ import 'package:eatvio_app/features/diets/repositories/diet_repository.dart';
|
||||
import 'package:eatvio_app/features/feed/presentation/bloc/diets_cubit/diets_state.dart';
|
||||
import 'package:eatvio_app/features/feed/repositories/feed_repository.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:eatvio_app/core/error_reporting/report_from.dart';
|
||||
|
||||
class DietsCubit extends Cubit<DietsState> {
|
||||
final FeedRepository feedRepository;
|
||||
@@ -109,6 +110,7 @@ class DietsCubit extends Cubit<DietsState> {
|
||||
),
|
||||
);
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
log(e.toString(), stackTrace: st);
|
||||
emit(
|
||||
state.copyWith(isLoading: false, errorMessage: e.toString()),
|
||||
@@ -144,7 +146,8 @@ class DietsCubit extends Cubit<DietsState> {
|
||||
),
|
||||
);
|
||||
}
|
||||
} catch (e) {
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
emit(
|
||||
state.copyWith(isLoading: false, errorMessage: e.toString()),
|
||||
);
|
||||
@@ -191,7 +194,8 @@ class DietsCubit extends Cubit<DietsState> {
|
||||
() async {
|
||||
try {
|
||||
await dietsRepository.likeDiet(id);
|
||||
} catch (e) {
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
log(e.toString());
|
||||
emit(
|
||||
state.copyWith(
|
||||
@@ -287,7 +291,8 @@ class DietsCubit extends Cubit<DietsState> {
|
||||
() async {
|
||||
try {
|
||||
await dietsRepository.addToFavorite(id);
|
||||
} catch (e) {
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
log(e.toString());
|
||||
showErrorToast('Произошла ошибка. Попробуйте ещё раз через некоторое время');
|
||||
emit(
|
||||
@@ -327,7 +332,8 @@ class DietsCubit extends Cubit<DietsState> {
|
||||
() async {
|
||||
try {
|
||||
await dietsRepository.removeFromFavorite(id);
|
||||
} catch (e) {
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
log(e.toString());
|
||||
showErrorToast('Произошла ошибка. Попробуйте ещё раз через некоторое время');
|
||||
emit(
|
||||
@@ -348,7 +354,8 @@ class DietsCubit extends Cubit<DietsState> {
|
||||
try {
|
||||
await dietsRepository.deleteDiet(dietId);
|
||||
return true;
|
||||
} catch (e) {
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import 'package:eatvio_app/features/feed/models/feed_blog_post_model.dart';
|
||||
import 'package:eatvio_app/features/feed/presentation/bloc/feed_cubit/feed_state.dart';
|
||||
import 'package:eatvio_app/features/feed/repositories/feed_repository.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:eatvio_app/core/error_reporting/report_from.dart';
|
||||
|
||||
class FeedCubit extends Cubit<FeedState> {
|
||||
final FeedRepository feedRepository;
|
||||
@@ -45,7 +46,8 @@ class FeedCubit extends Cubit<FeedState> {
|
||||
if (!isClosed) {
|
||||
emit(FeedState.loaded(feedBlogPostList: feedBlogPosts.feedBlogPostList, isLoading: false));
|
||||
}
|
||||
} catch (e) {
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
if (!isClosed) {
|
||||
emit(FeedState.error(errorMessage: e.toString()));
|
||||
}
|
||||
@@ -69,7 +71,8 @@ class FeedCubit extends Cubit<FeedState> {
|
||||
emit(FeedState.loaded(feedBlogPostList: [...(state as FeedStateLoaded).feedBlogPostList, ...feedBlogPosts.feedBlogPostList], isLoading: isLoading));
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
if (!isClosed) {
|
||||
emit(FeedState.error(errorMessage: e.toString()));
|
||||
}
|
||||
@@ -81,14 +84,48 @@ class FeedCubit extends Cubit<FeedState> {
|
||||
try {
|
||||
await feedRepository.likeBlogPost(id: id);
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
log(e.toString(), stackTrace: st);
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> unlikedPost(int id) async => await feedRepository.unlikedBlogPost(id: id);
|
||||
Future<void> unlikedPost(int id) async {
|
||||
try {
|
||||
await feedRepository.unlikedBlogPost(id: id);
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> viewPost(int id) async => await feedRepository.viewPost(id);
|
||||
Future<void> viewRecipe(String slug) async => await feedRepository.viewRecipe(slug);
|
||||
Future<void> viewDiet(int id) async => await feedRepository.viewDiet(id);
|
||||
Future<void> viewPlan(String slug) async => await feedRepository.viewPlan(slug);
|
||||
Future<void> viewPost(int id) async {
|
||||
try {
|
||||
await feedRepository.viewPost(id);
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> viewRecipe(String slug) async {
|
||||
try {
|
||||
await feedRepository.viewRecipe(slug);
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> viewDiet(int id) async {
|
||||
try {
|
||||
await feedRepository.viewDiet(id);
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> viewPlan(String slug) async {
|
||||
try {
|
||||
await feedRepository.viewPlan(slug);
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ import 'package:eatvio_app/features/feed/repositories/feed_repository.dart';
|
||||
import 'package:eatvio_app/features/plans/repositories/plan_repository.dart';
|
||||
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:eatvio_app/core/error_reporting/report_from.dart';
|
||||
|
||||
class PlansCubit extends Cubit<PlansState> {
|
||||
final FeedRepository feedRepository;
|
||||
@@ -41,6 +42,17 @@ class PlansCubit extends Cubit<PlansState> {
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> close() async {
|
||||
EasyDebounce.cancel('loadPlans');
|
||||
EasyDebounce.cancel('add_or_remove_plan_from_favorite');
|
||||
EasyDebounce.cancel('like_plan');
|
||||
likesStateSubscription.cancel();
|
||||
favoriteStateSubscription.cancel();
|
||||
commentsStateSubscription.cancel();
|
||||
await super.close();
|
||||
}
|
||||
|
||||
void changeDurationFilter(int index) {
|
||||
emit(state.copyWith(filterState: state.filterState.copyWith(durationIndex: index), errorMessage: null));
|
||||
EasyDebounce.debounce(
|
||||
@@ -168,6 +180,7 @@ class PlansCubit extends Cubit<PlansState> {
|
||||
),
|
||||
);
|
||||
} catch (e, stackTrace) {
|
||||
await reportFrom(e, stackTrace, this);
|
||||
log(e.toString());
|
||||
log(stackTrace.toString());
|
||||
emit(state.copyWith(isLoading: isLoading, errorMessage: e.toString()));
|
||||
@@ -199,7 +212,8 @@ class PlansCubit extends Cubit<PlansState> {
|
||||
),
|
||||
);
|
||||
}
|
||||
} catch (e) {
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
emit(state.copyWith(errorMessage: e.toString()));
|
||||
}
|
||||
}
|
||||
@@ -228,7 +242,8 @@ class PlansCubit extends Cubit<PlansState> {
|
||||
() async {
|
||||
try {
|
||||
await planRepository.addToFavorite(slug);
|
||||
} catch (e) {
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
log(e.toString());
|
||||
showErrorToast('Произошла ошибка. Попробуйте ещё раз через некоторое время');
|
||||
emit(
|
||||
@@ -268,7 +283,8 @@ class PlansCubit extends Cubit<PlansState> {
|
||||
() async {
|
||||
try {
|
||||
await planRepository.removeFromFavorite(slug);
|
||||
} catch (e) {
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
log(e.toString());
|
||||
showErrorToast('Произошла ошибка. Попробуйте ещё раз через некоторое время');
|
||||
emit(
|
||||
@@ -324,7 +340,8 @@ class PlansCubit extends Cubit<PlansState> {
|
||||
() async {
|
||||
try {
|
||||
await planRepository.likePlan(slug);
|
||||
} catch (e) {
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
log(e.toString());
|
||||
emit(
|
||||
state.copyWith(
|
||||
|
||||
@@ -3,6 +3,7 @@ import 'dart:developer';
|
||||
import 'package:eatvio_app/features/feed/presentation/bloc/profile_cubit/profile_state.dart';
|
||||
import 'package:eatvio_app/features/profile/repositories/profile_repository.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:eatvio_app/core/error_reporting/report_from.dart';
|
||||
|
||||
class FeedProfileCubit extends Cubit<ProfileState> {
|
||||
final ProfileRepository profileRepository;
|
||||
@@ -13,6 +14,7 @@ class FeedProfileCubit extends Cubit<ProfileState> {
|
||||
final profile = await profileRepository.getMyProfile();
|
||||
emit(state.copyWith(profile: profile));
|
||||
} catch (e, stackTrace) {
|
||||
await reportFrom(e, stackTrace, this);
|
||||
log(e.toString(), stackTrace: stackTrace);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ import 'package:eatvio_app/features/create_recipe/models/recipe_tag_model.dart';
|
||||
import 'package:eatvio_app/features/create_recipe/reporitories/recipe_repository.dart';
|
||||
import 'package:eatvio_app/features/recipe/repositories/about_recipe_repository.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:eatvio_app/core/error_reporting/report_from.dart';
|
||||
import 'dart:developer';
|
||||
|
||||
class RecipesCubit extends Cubit<RecipesState> {
|
||||
@@ -62,6 +63,7 @@ class RecipesCubit extends Cubit<RecipesState> {
|
||||
);
|
||||
lastPage = currentPage;
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
log(e.toString(), stackTrace: st);
|
||||
emit(state.copyWith(errorMessage: e.toString(), isLoading: false));
|
||||
}
|
||||
@@ -93,7 +95,8 @@ class RecipesCubit extends Cubit<RecipesState> {
|
||||
);
|
||||
}
|
||||
lastPage = currentPage;
|
||||
} catch (e) {
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
emit(state.copyWith(errorMessage: e.toString(), isLoading: false));
|
||||
}
|
||||
}
|
||||
@@ -132,7 +135,8 @@ class RecipesCubit extends Cubit<RecipesState> {
|
||||
() async {
|
||||
try {
|
||||
await aboutRecipeRepository.addToFavorite(slug);
|
||||
} catch (e) {
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
log(e.toString());
|
||||
showErrorToast('Произошла ошибка. Попробуйте ещё раз через некоторое время');
|
||||
emit(
|
||||
@@ -172,7 +176,8 @@ class RecipesCubit extends Cubit<RecipesState> {
|
||||
() async {
|
||||
try {
|
||||
await aboutRecipeRepository.removeFromFavorite(slug);
|
||||
} catch (e) {
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
log(e.toString());
|
||||
showErrorToast('Произошла ошибка. Попробуйте ещё раз через некоторое время');
|
||||
emit(
|
||||
@@ -228,7 +233,8 @@ class RecipesCubit extends Cubit<RecipesState> {
|
||||
() async {
|
||||
try {
|
||||
await aboutRecipeRepository.likeRecipe(slug);
|
||||
} catch (e) {
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
log(e.toString());
|
||||
emit(
|
||||
state.copyWith(
|
||||
@@ -305,7 +311,8 @@ class RecipesCubit extends Cubit<RecipesState> {
|
||||
try {
|
||||
await aboutRecipeRepository.deleteRecipe(slug);
|
||||
return true;
|
||||
} catch (e) {
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,7 +7,6 @@ import 'package:eatvio_app/features/feed/models/plan_pagination_model.dart';
|
||||
import 'package:eatvio_app/features/feed/models/recipes_model.dart';
|
||||
import 'package:eatvio_app/features/feed/models/view_model.dart';
|
||||
import 'package:eatvio_app/features/feed/services/feed_service.dart';
|
||||
import 'package:sentry_flutter/sentry_flutter.dart';
|
||||
|
||||
class FeedRepository {
|
||||
final FeedService feedService;
|
||||
@@ -15,191 +14,107 @@ class FeedRepository {
|
||||
FeedRepository({required this.feedService});
|
||||
|
||||
Future<FeedBlogPostSettingsModel> getFeedBlogPosts({String? query, int page = 1}) async {
|
||||
try {
|
||||
return (await feedService.getBlogPostList(page: page, query: query));
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
}
|
||||
return (await feedService.getBlogPostList(page: page, query: query));
|
||||
|
||||
}
|
||||
|
||||
Future<FeedBlogPostModel> getBlogPost({required int id}) async {
|
||||
try {
|
||||
return await feedService.getBlogPost(postId: id);
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
}
|
||||
return await feedService.getBlogPost(postId: id);
|
||||
|
||||
}
|
||||
|
||||
Future<List<Recipe>> getRecipes({String? query, List<int>? tags, int page = 1}) async {
|
||||
try {
|
||||
return (await feedService.getRecipes(query: query, tags: tags, page: page)).recipesList;
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
}
|
||||
return (await feedService.getRecipes(query: query, tags: tags, page: page)).recipesList;
|
||||
|
||||
}
|
||||
|
||||
Future<DietsPagination> getDiets({int page = 1, String? query, String? types, int? duration, String? sorting}) async {
|
||||
try {
|
||||
return (await feedService.getDiets(page: page, query: query, types: types, duration: duration, sorting: sorting));
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
}
|
||||
return (await feedService.getDiets(page: page, query: query, types: types, duration: duration, sorting: sorting));
|
||||
|
||||
}
|
||||
|
||||
Future<PlanPaginationModel> getPlans({int page = 1, String? query, String? types, int? duration, int? minPrice, int? maxPrice}) async {
|
||||
try {
|
||||
return (await feedService.getPlans(page: page, query: query, types: types, duration: duration, minPrice: minPrice, maxPrice: maxPrice));
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
}
|
||||
return (await feedService.getPlans(page: page, query: query, types: types, duration: duration, minPrice: minPrice, maxPrice: maxPrice));
|
||||
|
||||
}
|
||||
|
||||
Future<CommentModel> getBlogPostComments({required String id}) async {
|
||||
try {
|
||||
return (await feedService.getBlogPostComments(id: id));
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
}
|
||||
return (await feedService.getBlogPostComments(id: id));
|
||||
|
||||
}
|
||||
|
||||
Future<void> sendBlogPostComment({required String id, required String commentText, int? parentCommentId}) async {
|
||||
try {
|
||||
await feedService.sendBlogPostComment(id: id, body: commentText, parentCommentId: parentCommentId);
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
}
|
||||
await feedService.sendBlogPostComment(id: id, body: commentText, parentCommentId: parentCommentId);
|
||||
|
||||
}
|
||||
|
||||
Future<CommentModel> getDietsComments({required String id}) async {
|
||||
try {
|
||||
return (await feedService.getDietsComments(id: id));
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
}
|
||||
return (await feedService.getDietsComments(id: id));
|
||||
|
||||
}
|
||||
|
||||
Future<void> sendDietsComment({required String id, required String commentText, int? parentCommentId}) async {
|
||||
try {
|
||||
await feedService.sendDietsComment(id: id, body: commentText, parentCommentId: parentCommentId);
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
}
|
||||
await feedService.sendDietsComment(id: id, body: commentText, parentCommentId: parentCommentId);
|
||||
|
||||
}
|
||||
|
||||
Future<CommentModel> getRecipesComments({required String id}) async {
|
||||
try {
|
||||
return (await feedService.getRecipesComments(id: id));
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
}
|
||||
return (await feedService.getRecipesComments(id: id));
|
||||
|
||||
}
|
||||
|
||||
Future<void> sendRecipesComment({required String id, required String commentText, int? parentCommentId}) async {
|
||||
try {
|
||||
await feedService.sendRecipesComment(id: id, body: commentText, parentCommentId: parentCommentId);
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
}
|
||||
await feedService.sendRecipesComment(id: id, body: commentText, parentCommentId: parentCommentId);
|
||||
|
||||
}
|
||||
|
||||
Future<CommentModel> getPlansComments({required String slug}) async {
|
||||
try {
|
||||
return (await feedService.getPlansComments(slug: slug));
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
}
|
||||
return (await feedService.getPlansComments(slug: slug));
|
||||
|
||||
}
|
||||
|
||||
Future<void> sendPlansComment({required String slug, required String commentText, int? parentCommentId}) async {
|
||||
try {
|
||||
await feedService.sendPlansComment(slug: slug, body: commentText, parentCommentId: parentCommentId);
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
}
|
||||
await feedService.sendPlansComment(slug: slug, body: commentText, parentCommentId: parentCommentId);
|
||||
|
||||
}
|
||||
|
||||
Future<void> likeBlogPost({required int id}) async {
|
||||
try {
|
||||
await feedService.likeBlogPost(id: id);
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
}
|
||||
await feedService.likeBlogPost(id: id);
|
||||
|
||||
}
|
||||
|
||||
Future<void> unlikedBlogPost({required int id}) async {
|
||||
try {
|
||||
await feedService.unlikedBlogPost(id: id);
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
}
|
||||
await feedService.unlikedBlogPost(id: id);
|
||||
|
||||
}
|
||||
|
||||
Future<List<FeedConsultantModel>> getConsultants([String? name]) async {
|
||||
try {
|
||||
return (await feedService.getConsultants(name: name)).data;
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
}
|
||||
return (await feedService.getConsultants(name: name)).data;
|
||||
|
||||
}
|
||||
|
||||
Future<void> viewPost(int id) async {
|
||||
try {
|
||||
return (await feedService.viewPost(id: id));
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
}
|
||||
return (await feedService.viewPost(id: id));
|
||||
|
||||
}
|
||||
|
||||
Future<void> viewRecipe(String slug) async {
|
||||
try {
|
||||
return (await feedService.viewRecipe(slug: slug));
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
}
|
||||
return (await feedService.viewRecipe(slug: slug));
|
||||
|
||||
}
|
||||
|
||||
Future<void> viewDiet(int id) async {
|
||||
try {
|
||||
return (await feedService.viewDiet(id: id));
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
}
|
||||
return (await feedService.viewDiet(id: id));
|
||||
|
||||
}
|
||||
|
||||
Future<void> viewPlan(String slug) async {
|
||||
try {
|
||||
return (await feedService.viewPlan(slug: slug));
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
}
|
||||
return (await feedService.viewPlan(slug: slug));
|
||||
|
||||
}
|
||||
|
||||
Future<void> viewContent({required ViewModel viewModel}) async {
|
||||
try {
|
||||
await feedService.viewContent(viewModel: viewModel);
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
}
|
||||
await feedService.viewContent(viewModel: viewModel);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ import 'package:eatvio_app/features/finances_and_consultations_archive/cubit/arc
|
||||
import 'package:eatvio_app/features/finances_and_consultations_archive/models/statistic_model.dart';
|
||||
import 'package:eatvio_app/features/finances_and_consultations_archive/period_enum.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:eatvio_app/core/error_reporting/report_from.dart';
|
||||
|
||||
class ConsultationsArchiveCubit extends Cubit<ConsultationsArchiveState> {
|
||||
final ConsultationsRepository consultationsRepository;
|
||||
@@ -34,7 +35,8 @@ class ConsultationsArchiveCubit extends Cubit<ConsultationsArchiveState> {
|
||||
: FiltersComparisonEnum.equal,
|
||||
);
|
||||
emit(state.copyWith(consultations: consultations, isLoading: false));
|
||||
} catch (e) {
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
emit(state.copyWith(isLoading: false));
|
||||
log(e.toString());
|
||||
}
|
||||
@@ -55,7 +57,8 @@ class ConsultationsArchiveCubit extends Cubit<ConsultationsArchiveState> {
|
||||
emit(state.copyWith(isLoading: true));
|
||||
final statistic = await consultationsRepository.getStatistic();
|
||||
emit(state.copyWith(statisticModel: statistic, isLoading: false));
|
||||
} catch (e) {
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
emit(state.copyWith(isLoading: false));
|
||||
log(e.toString());
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import 'package:eatvio_app/features/consultations/repositories/consultations_rep
|
||||
import 'package:eatvio_app/features/finances_and_consultations_archive/cubit/consultant_finances/consultant_finances_state.dart';
|
||||
import 'package:eatvio_app/features/finances_and_consultations_archive/period_enum.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:eatvio_app/core/error_reporting/report_from.dart';
|
||||
|
||||
class ConsultantFinancesCubit extends Cubit<ConsultantFinancesState> {
|
||||
final ConsultationsRepository consultationsRepository;
|
||||
@@ -22,7 +23,8 @@ class ConsultantFinancesCubit extends Cubit<ConsultantFinancesState> {
|
||||
state.periodFilterStatus == PeriodFilterStatus.all ? null : FiltersComparisonEnum.greaterThanOrEqual,
|
||||
);
|
||||
emit(state.copyWith(financesModels: consultantFinances, isLoading: false));
|
||||
} catch (e) {
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
emit(state.copyWith(financesModels: [], isLoading: false));
|
||||
log(e.toString());
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import 'package:eatvio_app/features/consultations/repositories/consultations_rep
|
||||
import 'package:eatvio_app/features/finances_and_consultations_archive/cubit/user_purchases/user_purchases_state.dart';
|
||||
import 'package:eatvio_app/features/finances_and_consultations_archive/period_enum.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:eatvio_app/core/error_reporting/report_from.dart';
|
||||
|
||||
class UserPurchasesCubit extends Cubit<UserPurchasesState> {
|
||||
final ConsultationsRepository consultationsRepository;
|
||||
@@ -23,7 +24,8 @@ class UserPurchasesCubit extends Cubit<UserPurchasesState> {
|
||||
);
|
||||
|
||||
emit(state.copyWith(purchasesModels: purchasesModels, isLoading: false));
|
||||
} catch (e) {
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
emit(state.copyWith(purchasesModels: [], isLoading: false));
|
||||
log(e.toString());
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import 'package:eatvio_app/features/glossary/models/glossary_model.dart';
|
||||
import 'package:eatvio_app/features/glossary/services/glossary_service.dart';
|
||||
import 'package:sentry_flutter/sentry_flutter.dart';
|
||||
|
||||
class GlossaryRepository {
|
||||
final GlossaryService glossaryService;
|
||||
@@ -10,11 +9,7 @@ class GlossaryRepository {
|
||||
});
|
||||
|
||||
Future<List<GlossaryModel>> getGlossaryListByQuery(String query) async {
|
||||
try {
|
||||
return (await glossaryService.getGlossaryByQuery(query: query)).glossariesList;
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
}
|
||||
return (await glossaryService.getGlossaryByQuery(query: query)).glossariesList;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ import 'dart:developer';
|
||||
import 'package:eatvio_app/features/menu/presentation/bloc/menu_cubit/menu_state.dart';
|
||||
import 'package:eatvio_app/features/profile/repositories/profile_repository.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:eatvio_app/core/error_reporting/report_from.dart';
|
||||
|
||||
class MenuCubit extends Cubit<MenuState> {
|
||||
final ProfileRepository profileRepository;
|
||||
@@ -12,7 +13,8 @@ class MenuCubit extends Cubit<MenuState> {
|
||||
try {
|
||||
final passKey = await profileRepository.getPassKey(routeName: 'product_nutritional_value.index', routeParams: {});
|
||||
return passKey;
|
||||
} catch (e) {
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
log(e.toString());
|
||||
}
|
||||
return null;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import 'dart:developer';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:eatvio_app/core/error_reporting/report_from.dart';
|
||||
import 'package:eatvio_app/features/menu/presentation/bloc/notification_settings_cubit/notification_settings_state.dart';
|
||||
import 'package:eatvio_app/features/menu/repositories/notification_settings_repository.dart';
|
||||
|
||||
@@ -16,6 +17,7 @@ class NotificationSettingsCubit extends Cubit<NotificationSettingsState> {
|
||||
final notificationSettings = await _notificationSettingsRepository.getNotificationSettings();
|
||||
emit(NotificationSettingsStateLoaded(notificationSettings: notificationSettings));
|
||||
} catch (e, stackTrace) {
|
||||
await reportFrom(e, stackTrace, this);
|
||||
log('Error getting notification settings: $e', stackTrace: stackTrace);
|
||||
emit(NotificationSettingsStateError(errorMessage: e.toString()));
|
||||
}
|
||||
@@ -26,6 +28,7 @@ class NotificationSettingsCubit extends Cubit<NotificationSettingsState> {
|
||||
final notificationSettings = await _notificationSettingsRepository.updateNotificationSettings(data);
|
||||
emit(NotificationSettingsStateLoaded(notificationSettings: notificationSettings));
|
||||
} catch (e, stackTrace) {
|
||||
await reportFrom(e, stackTrace, this);
|
||||
log('Error updating notification settings: $e', stackTrace: stackTrace);
|
||||
emit(NotificationSettingsStateError(errorMessage: e.toString()));
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import 'package:eatvio_app/features/menu/presentation/blocked_user_cubit/blocked_users_state.dart';
|
||||
import 'package:eatvio_app/features/menu/presentation/repositories/blocked_users_repository.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:eatvio_app/core/error_reporting/report_from.dart';
|
||||
|
||||
class BlockedUsersCubit extends Cubit<BlockedUsersState> {
|
||||
final BlockedUsersRepository blockedUsersRepository;
|
||||
@@ -13,17 +14,26 @@ class BlockedUsersCubit extends Cubit<BlockedUsersState> {
|
||||
try {
|
||||
emit(BlockedUsersState.loaded(profilesList: await blockedUsersRepository.getBlockedUsers()));
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
emit(BlockedUsersState.error(errorMessage: '$e $st'));
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> blockUser(String slug) async {
|
||||
await blockedUsersRepository.blockUserBySlug(slug);
|
||||
await getBlockedUsers();
|
||||
try {
|
||||
await blockedUsersRepository.blockUserBySlug(slug);
|
||||
await getBlockedUsers();
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> unblockUser(String slug) async {
|
||||
await blockedUsersRepository.unblockUserBySlug(slug);
|
||||
await getBlockedUsers();
|
||||
try {
|
||||
await blockedUsersRepository.unblockUserBySlug(slug);
|
||||
await getBlockedUsers();
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:eatvio_app/core/app_config.dart';
|
||||
import 'package:sentry_flutter/sentry_flutter.dart';
|
||||
import 'package:eatvio_app/core/error_reporting/error_reporter.dart';
|
||||
import 'package:eatvio_app/core/const.dart';
|
||||
import 'package:eatvio_app/core/theme/custom_text_style.dart';
|
||||
import 'package:eatvio_app/core/token_storage.dart';
|
||||
@@ -144,7 +144,7 @@ class MenuScreen extends StatelessWidget {
|
||||
try {
|
||||
await sl<Dio>().post('${sl<AppConfig>().baseUrl}/api/profile/logout');
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
await sl<ErrorReporter>().report(e, s, origin: 'MenuScreen');
|
||||
} finally {
|
||||
await sl<WsManager>().clear();
|
||||
await TokenStorage.removeTokenInStorage();
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
import 'dart:developer';
|
||||
import 'package:eatvio_app/features/menu/services/blocked_users_service.dart';
|
||||
import 'package:eatvio_app/features/profile/models/profile_model.dart';
|
||||
import 'package:sentry_flutter/sentry_flutter.dart';
|
||||
|
||||
class BlockedUsersRepository {
|
||||
final BlockedUserService blockedUserService;
|
||||
@@ -11,40 +9,25 @@ class BlockedUsersRepository {
|
||||
});
|
||||
|
||||
Future<List<ProfileModel>> getBlockedUsers() async {
|
||||
try {
|
||||
return (await blockedUserService.getBlockedUsers()).profilesList;
|
||||
} catch (e, st) {
|
||||
log(e.toString(), stackTrace: st);
|
||||
await Sentry.captureException(e, stackTrace: st);
|
||||
rethrow;
|
||||
}
|
||||
return (await blockedUserService.getBlockedUsers()).profilesList;
|
||||
|
||||
}
|
||||
|
||||
Future<void> blockUserBySlug(String slug) async {
|
||||
try {
|
||||
return await blockedUserService.blockUser(
|
||||
data: {
|
||||
'slug': slug,
|
||||
},
|
||||
);
|
||||
} catch (e, st) {
|
||||
log(e.toString(), stackTrace: st);
|
||||
await Sentry.captureException(e, stackTrace: st);
|
||||
rethrow;
|
||||
}
|
||||
return await blockedUserService.blockUser(
|
||||
data: {
|
||||
'slug': slug,
|
||||
},
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
Future<void> unblockUserBySlug(String slug) async {
|
||||
try {
|
||||
return await blockedUserService.unblockUser(
|
||||
data: {
|
||||
'slug': slug,
|
||||
},
|
||||
);
|
||||
} catch (e, st) {
|
||||
log(e.toString(), stackTrace: st);
|
||||
await Sentry.captureException(e, stackTrace: st);
|
||||
rethrow;
|
||||
}
|
||||
return await blockedUserService.unblockUser(
|
||||
data: {
|
||||
'slug': slug,
|
||||
},
|
||||
);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import 'package:eatvio_app/features/menu/models/notification_settings_model.dart';
|
||||
import 'package:eatvio_app/features/menu/services/notification_settings_service.dart';
|
||||
import 'package:sentry_flutter/sentry_flutter.dart';
|
||||
|
||||
class NotificationSettingsRepository {
|
||||
final NotificationSettingsService _notificationSettingsService;
|
||||
@@ -8,20 +7,12 @@ class NotificationSettingsRepository {
|
||||
NotificationSettingsRepository(this._notificationSettingsService);
|
||||
|
||||
Future<NotificationSettingsModel> getNotificationSettings() async {
|
||||
try {
|
||||
return await _notificationSettingsService.getNotificationSettings();
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
}
|
||||
return await _notificationSettingsService.getNotificationSettings();
|
||||
|
||||
}
|
||||
|
||||
Future<NotificationSettingsModel> updateNotificationSettings(Map<String, dynamic> data) async {
|
||||
try {
|
||||
return await _notificationSettingsService.updateNotificationSettings(data: data);
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
}
|
||||
return await _notificationSettingsService.updateNotificationSettings(data: data);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ import 'package:eatvio_app/features/feed/models/diets_pagination_model.dart';
|
||||
import 'package:eatvio_app/features/my_diets/presentation/cubit/my_diets_state.dart';
|
||||
import 'package:eatvio_app/features/my_diets/repositories/my_diets_repository.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:eatvio_app/core/error_reporting/report_from.dart';
|
||||
|
||||
class MyDietsCubit extends Cubit<MyDietsState> {
|
||||
final MyDietsRepository myDietsRepository;
|
||||
@@ -212,6 +213,7 @@ class MyDietsCubit extends Cubit<MyDietsState> {
|
||||
),
|
||||
);
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
log(e.toString(), stackTrace: st);
|
||||
emit(
|
||||
state.copyWith(activeDietsError: e.toString()),
|
||||
@@ -242,7 +244,8 @@ class MyDietsCubit extends Cubit<MyDietsState> {
|
||||
error: null,
|
||||
),
|
||||
);
|
||||
} catch (e) {
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
emit(
|
||||
state.copyWith(draftDietsError: e.toString()),
|
||||
);
|
||||
@@ -272,7 +275,8 @@ class MyDietsCubit extends Cubit<MyDietsState> {
|
||||
error: null,
|
||||
),
|
||||
);
|
||||
} catch (e) {
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
emit(
|
||||
state.copyWith(personalDietsError: e.toString()),
|
||||
);
|
||||
@@ -283,7 +287,8 @@ class MyDietsCubit extends Cubit<MyDietsState> {
|
||||
try {
|
||||
await myDietsRepository.deleteDiet(dietId);
|
||||
return true;
|
||||
} catch (e) {
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
emit(
|
||||
state.copyWith(error: e.toString()),
|
||||
);
|
||||
@@ -299,6 +304,7 @@ class MyDietsCubit extends Cubit<MyDietsState> {
|
||||
);
|
||||
return statusCode;
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
log(e.toString(), stackTrace: st);
|
||||
return 0;
|
||||
}
|
||||
@@ -312,6 +318,7 @@ class MyDietsCubit extends Cubit<MyDietsState> {
|
||||
);
|
||||
return true;
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
log(e.toString(), stackTrace: st);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import 'package:eatvio_app/features/feed/models/diets_pagination_model.dart';
|
||||
import 'package:eatvio_app/features/my_diets/services/my_diets_service.dart';
|
||||
import 'package:sentry_flutter/sentry_flutter.dart';
|
||||
|
||||
class MyDietsRepository {
|
||||
final MyDietsService myDietsService;
|
||||
@@ -8,12 +7,8 @@ class MyDietsRepository {
|
||||
MyDietsRepository({required this.myDietsService});
|
||||
|
||||
Future<void> deleteDiet(int dietId) async {
|
||||
try {
|
||||
await myDietsService.deleteDiet(dietId: dietId);
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
}
|
||||
await myDietsService.deleteDiet(dietId: dietId);
|
||||
|
||||
}
|
||||
|
||||
Future<DietsPagination> getDiets({
|
||||
@@ -24,18 +19,14 @@ class MyDietsRepository {
|
||||
String? sorting,
|
||||
String? state,
|
||||
}) async {
|
||||
try {
|
||||
return (await myDietsService.getDiets(
|
||||
page: page,
|
||||
query: query,
|
||||
types: types,
|
||||
duration: duration,
|
||||
sorting: sorting,
|
||||
state: state,
|
||||
));
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
}
|
||||
return (await myDietsService.getDiets(
|
||||
page: page,
|
||||
query: query,
|
||||
types: types,
|
||||
duration: duration,
|
||||
sorting: sorting,
|
||||
state: state,
|
||||
));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ import 'package:eatvio_app/features/my_finance/models/payment_url_model.dart';
|
||||
import 'package:eatvio_app/features/my_finance/presentation/cubit/user_cards_cubit/user_cards_state.dart';
|
||||
import 'package:eatvio_app/features/my_finance/repositories/cards_repository.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:eatvio_app/core/error_reporting/report_from.dart';
|
||||
|
||||
class UserCardsCubit extends Cubit<UserCardsState> {
|
||||
final CardsRepository cardsRepository;
|
||||
@@ -15,6 +16,7 @@ class UserCardsCubit extends Cubit<UserCardsState> {
|
||||
try {
|
||||
return await cardsRepository.addCard();
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
log(e.toString(), stackTrace: st);
|
||||
}
|
||||
return null;
|
||||
@@ -27,6 +29,7 @@ class UserCardsCubit extends Cubit<UserCardsState> {
|
||||
final cards = await cardsRepository.getCards();
|
||||
emit(state.copyWith(cards: cards, state: BaseState.success));
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
log(e.toString(), stackTrace: st);
|
||||
emit(state.copyWith(state: BaseState.error, error: e.toString()));
|
||||
}
|
||||
@@ -47,6 +50,7 @@ class UserCardsCubit extends Cubit<UserCardsState> {
|
||||
try {
|
||||
await cardsRepository.markAsDefault(id: id);
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
emit(state.copyWith(cards: oldCards));
|
||||
log(e.toString(), stackTrace: st);
|
||||
}
|
||||
@@ -61,6 +65,7 @@ class UserCardsCubit extends Cubit<UserCardsState> {
|
||||
emit(state.copyWith(cards: cards));
|
||||
await cardsRepository.deleteCard(id: id);
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
emit(state.copyWith(cards: oldCards, error: e.toString(), state: BaseState.error));
|
||||
log(e.toString(), stackTrace: st);
|
||||
}
|
||||
@@ -71,6 +76,7 @@ class UserCardsCubit extends Cubit<UserCardsState> {
|
||||
await cardsRepository.collectCharge(chosenPlaId: chosenPlaId);
|
||||
return true;
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
log(e.toString(), stackTrace: st);
|
||||
}
|
||||
return false;
|
||||
|
||||
@@ -1,53 +1,32 @@
|
||||
import 'package:eatvio_app/features/my_finance/models/card_model.dart';
|
||||
import 'package:eatvio_app/features/my_finance/models/payment_url_model.dart';
|
||||
import 'package:eatvio_app/features/my_finance/services/cards_service.dart';
|
||||
import 'package:sentry_flutter/sentry_flutter.dart';
|
||||
|
||||
class CardsRepository {
|
||||
final CardsService cardsService;
|
||||
CardsRepository({required this.cardsService});
|
||||
Future<PaymentUrlModel> addCard() async {
|
||||
try {
|
||||
return await cardsService.addCard();
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
}
|
||||
return await cardsService.addCard();
|
||||
|
||||
}
|
||||
|
||||
Future<List<CardModel>> getCards() async {
|
||||
try {
|
||||
return await cardsService.getCards();
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
}
|
||||
return await cardsService.getCards();
|
||||
|
||||
}
|
||||
|
||||
Future<void> markAsDefault({required int id}) async {
|
||||
try {
|
||||
await cardsService.markAsDefault(id: id);
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
}
|
||||
await cardsService.markAsDefault(id: id);
|
||||
|
||||
}
|
||||
|
||||
Future<void> deleteCard({required int id}) async {
|
||||
try {
|
||||
await cardsService.deleteCard(id: id);
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
}
|
||||
await cardsService.deleteCard(id: id);
|
||||
|
||||
}
|
||||
|
||||
Future<void> collectCharge({required int chosenPlaId}) async {
|
||||
try {
|
||||
await cardsService.collectCharge(chosenPlanId: chosenPlaId);
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
}
|
||||
await cardsService.collectCharge(chosenPlanId: chosenPlaId);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ import 'package:eatvio_app/core/const.dart';
|
||||
import 'package:eatvio_app/features/my_plans/presentation/cubit/my_plans_state.dart';
|
||||
import 'package:eatvio_app/features/my_plans/repositories/my_diets_repository.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:eatvio_app/core/error_reporting/report_from.dart';
|
||||
|
||||
class MyPlansCubit extends Cubit<MyPlansState> {
|
||||
final MyPlansRepository myPlansRepository;
|
||||
@@ -145,7 +146,8 @@ class MyPlansCubit extends Cubit<MyPlansState> {
|
||||
maxActivePlanPrice: maxPlanPrice,
|
||||
),
|
||||
);
|
||||
} catch (e) {
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
emit(
|
||||
state.copyWith(error: e.toString()),
|
||||
);
|
||||
@@ -185,7 +187,8 @@ class MyPlansCubit extends Cubit<MyPlansState> {
|
||||
maxDraftPlanPrice: maxPlanPrice,
|
||||
),
|
||||
);
|
||||
} catch (e) {
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
emit(
|
||||
state.copyWith(error: e.toString()),
|
||||
);
|
||||
@@ -197,7 +200,8 @@ class MyPlansCubit extends Cubit<MyPlansState> {
|
||||
await myPlansRepository.deletePlan(slug);
|
||||
await loadAllPlans();
|
||||
return true;
|
||||
} catch (e) {
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
emit(
|
||||
state.copyWith(error: e.toString()),
|
||||
);
|
||||
@@ -209,7 +213,8 @@ class MyPlansCubit extends Cubit<MyPlansState> {
|
||||
try {
|
||||
await myPlansRepository.unpublish(slug);
|
||||
return true;
|
||||
} catch (e) {
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
import 'dart:developer';
|
||||
|
||||
import 'package:eatvio_app/features/feed/models/plan_pagination_model.dart';
|
||||
import 'package:eatvio_app/features/my_plans/services/my_plans_service.dart';
|
||||
import 'package:sentry_flutter/sentry_flutter.dart';
|
||||
|
||||
class MyPlansRepository {
|
||||
final MyPlansService myPlansService;
|
||||
@@ -10,30 +7,17 @@ class MyPlansRepository {
|
||||
MyPlansRepository({required this.myPlansService});
|
||||
|
||||
Future<void> deletePlan(String slug) async {
|
||||
try {
|
||||
await myPlansService.deletePlan(slug: slug);
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
}
|
||||
await myPlansService.deletePlan(slug: slug);
|
||||
|
||||
}
|
||||
|
||||
Future<PlanPaginationModel> getPlans({int page = 1, String? query, String? types, int? duration, int? minPrice, int? maxPrice}) async {
|
||||
try {
|
||||
return (await myPlansService.getPlans(page: page, query: query, types: types, duration: duration, minPrice: minPrice, maxPrice: maxPrice));
|
||||
} catch (e, st) {
|
||||
log(e.toString(), error: e, stackTrace: st);
|
||||
await Sentry.captureException(e, stackTrace: st);
|
||||
rethrow;
|
||||
}
|
||||
return (await myPlansService.getPlans(page: page, query: query, types: types, duration: duration, minPrice: minPrice, maxPrice: maxPrice));
|
||||
|
||||
}
|
||||
|
||||
Future<void> unpublish(String slug) async {
|
||||
try {
|
||||
return await myPlansService.unpublish(slug: slug);
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
}
|
||||
return await myPlansService.unpublish(slug: slug);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ import 'package:eatvio_app/features/notifications/models/notification_model.dart
|
||||
import 'package:eatvio_app/features/notifications/presentation/notifications_cubit/notifications_state.dart';
|
||||
import 'package:eatvio_app/features/notifications/repository/notifications_repository.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:eatvio_app/core/error_reporting/report_from.dart';
|
||||
|
||||
class NotificationsCubit extends Cubit<NotificationsState> {
|
||||
final List<BaseNotificationModel> _notifications = [];
|
||||
@@ -16,10 +17,14 @@ class NotificationsCubit extends Cubit<NotificationsState> {
|
||||
NotificationsCubit({required this.wsManager, required this.notificationsRepository}) : super(const NotificationsState.empty());
|
||||
|
||||
Future<void> connectToWebSocket() async {
|
||||
await _newNotificationsSubscription?.cancel();
|
||||
_newNotificationsSubscription = wsManager.newNotificationsStream?.listen((event) {
|
||||
_handleNotification(event.data);
|
||||
});
|
||||
try {
|
||||
await _newNotificationsSubscription?.cancel();
|
||||
_newNotificationsSubscription = wsManager.newNotificationsStream?.listen((event) {
|
||||
_handleNotification(event.data);
|
||||
});
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
}
|
||||
}
|
||||
|
||||
BaseNotificationModel _parseNotification(Map<String, dynamic> notificationJson, NotificationType type) {
|
||||
@@ -341,12 +346,21 @@ class NotificationsCubit extends Cubit<NotificationsState> {
|
||||
),
|
||||
NotificationType.unknown => UnknownNotification(type: type, createdAt: parseDate(createdAt ?? jsonEncode(notificationJson))),
|
||||
};
|
||||
} catch (e) {
|
||||
} catch (e, st) {
|
||||
unawaited(reportFrom(e, st, this));
|
||||
return UnknownNotification(type: NotificationType.unknown, createdAt: DateTime.now());
|
||||
}
|
||||
}
|
||||
|
||||
void _handleNotification(String notificationData) {
|
||||
try {
|
||||
_handleNotificationParsed(notificationData);
|
||||
} catch (e, st) {
|
||||
unawaited(reportFrom(e, st, this));
|
||||
}
|
||||
}
|
||||
|
||||
void _handleNotificationParsed(String notificationData) {
|
||||
final json = jsonDecode(notificationData) as Map<String, dynamic>;
|
||||
|
||||
// Улучшенная логика определения типа уведомления (порядок: database_type → type → notification_class_name)
|
||||
@@ -420,6 +434,7 @@ class NotificationsCubit extends Cubit<NotificationsState> {
|
||||
);
|
||||
}
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
log(e.toString(), stackTrace: st);
|
||||
}
|
||||
}
|
||||
@@ -456,6 +471,7 @@ class NotificationsCubit extends Cubit<NotificationsState> {
|
||||
emit(currentState.copyWith(isLoadingMore: false));
|
||||
}
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
log(e.toString(), stackTrace: st);
|
||||
emit(currentState.copyWith(isLoadingMore: false));
|
||||
}
|
||||
@@ -471,6 +487,7 @@ class NotificationsCubit extends Cubit<NotificationsState> {
|
||||
await getNotifications();
|
||||
emit(currentState.copyWith(isLoading: false, hasUnreadNotifications: false));
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
log(e.toString(), stackTrace: st);
|
||||
emit(currentState.copyWith(isLoading: false));
|
||||
}
|
||||
|
||||
@@ -1,27 +1,16 @@
|
||||
import 'dart:developer';
|
||||
import 'package:eatvio_app/features/notifications/service/notifications_service.dart';
|
||||
import 'package:sentry_flutter/sentry_flutter.dart';
|
||||
|
||||
class NotificationsRepository {
|
||||
final NotificationsService notificationsService;
|
||||
NotificationsRepository({required this.notificationsService});
|
||||
|
||||
Future<Map<String, dynamic>?> getNotifications({required int page}) async {
|
||||
try {
|
||||
return await notificationsService.getNotifications(page: page);
|
||||
} catch (e, s) {
|
||||
log(e.toString());
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
}
|
||||
return await notificationsService.getNotifications(page: page);
|
||||
|
||||
}
|
||||
|
||||
Future<void> markNotificationsAsRead() async {
|
||||
try {
|
||||
await notificationsService.markNotificationsAsRead();
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
}
|
||||
await notificationsService.markNotificationsAsRead();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ import 'package:eatvio_app/features/chat/repositories/chat_repository.dart';
|
||||
import 'package:eatvio_app/features/order_info/cubit/order_info_state.dart';
|
||||
import 'package:eatvio_app/features/profile/repositories/profile_repository.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:eatvio_app/core/error_reporting/report_from.dart';
|
||||
|
||||
class OrderInfoCubit extends Cubit<OrderInfoState> {
|
||||
OrderInfoCubit({required this.chatRepository, required this.profileRepository}) : super(OrderInfoState());
|
||||
@@ -15,22 +16,32 @@ class OrderInfoCubit extends Cubit<OrderInfoState> {
|
||||
if (plan == null) return null;
|
||||
final paymentModel = await chatRepository.getPaymentLink(id: plan.id);
|
||||
return paymentModel.paymentUrl;
|
||||
} catch (e) {
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
log(e.toString());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> getChosenPlan({required int id, String? customerSlug}) async {
|
||||
Future<void> getChosenPlan({required int id, String? customerSlug, bool isConsultantView = false}) async {
|
||||
try {
|
||||
emit(state.copyWith(isLoading: true));
|
||||
final chosenPlan = await chatRepository.getChosenPlan(id: id);
|
||||
|
||||
if (customerSlug != null) {
|
||||
final profile = await profileRepository.getProfileBySlug(customerSlug);
|
||||
emit(state.copyWith(customerProfile: profile));
|
||||
emit(state.copyWith(customerProfile: profile, isLoading: false, chosenPlan: chosenPlan));
|
||||
return;
|
||||
}
|
||||
if (isConsultantView) {
|
||||
final chatRoom = await chatRepository.getChatRoom(chosenPlan.chatId);
|
||||
final customerSlug = chatRoom.users.receiver.slug;
|
||||
final profile = await profileRepository.getProfileBySlug(customerSlug);
|
||||
emit(state.copyWith(customerProfile: profile, isLoading: false, chosenPlan: chosenPlan));
|
||||
}
|
||||
emit(state.copyWith(isLoading: false, chosenPlan: chosenPlan));
|
||||
} catch (e) {
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
log(e.toString());
|
||||
emit(state.copyWith(isLoading: false));
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import 'package:eatvio_app/core/locator_service.dart';
|
||||
import 'package:eatvio_app/core/routing/route_constants.dart';
|
||||
import 'package:eatvio_app/core/theme/custom_text_style.dart';
|
||||
import 'package:eatvio_app/core/theme/theme_helper.dart';
|
||||
import 'package:eatvio_app/features/cancel_plan_bottom_sheet/cancel_plan_bottom_sheet.dart';
|
||||
@@ -24,20 +25,21 @@ import 'package:go_router/go_router.dart';
|
||||
class InfoByOrderScreen extends StatelessWidget {
|
||||
static const name = 'infoByOrderScreen';
|
||||
static const path = '/info-by-order-screen';
|
||||
const InfoByOrderScreen({super.key, this.successfulPayment, required this.planId, this.customerSlug});
|
||||
const InfoByOrderScreen({super.key, this.successfulPayment, required this.planId, this.customerSlug, this.isConsultantView = false});
|
||||
final bool? successfulPayment;
|
||||
final int planId;
|
||||
final String? customerSlug;
|
||||
final bool isConsultantView;
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return BlocProvider(
|
||||
create: (context) => sl<OrderInfoCubit>()..getChosenPlan(id: planId, customerSlug: customerSlug),
|
||||
create: (context) => sl<OrderInfoCubit>()..getChosenPlan(id: planId, customerSlug: customerSlug, isConsultantView: isConsultantView),
|
||||
child: InfoByOrderScreenContent(successfulPayment: successfulPayment, planId: planId, customerSlug: customerSlug),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class InfoByOrderScreenContent extends StatefulWidget {
|
||||
class InfoByOrderScreenContent extends StatefulWidget {
|
||||
const InfoByOrderScreenContent({super.key, required this.planId, required this.successfulPayment, this.customerSlug});
|
||||
final int planId;
|
||||
final bool? successfulPayment;
|
||||
@@ -61,7 +63,11 @@ class _InfoByOrderScreenContentState extends State<InfoByOrderScreenContent> {
|
||||
leading: IconButton(
|
||||
icon: const Icon(Icons.arrow_back),
|
||||
onPressed: () {
|
||||
GoRouter.of(context).pop();
|
||||
if (GoRouter.of(context).canPop()) {
|
||||
GoRouter.of(context).pop();
|
||||
} else {
|
||||
GoRouter.of(context).go(RouteConstants.feedScreen);
|
||||
}
|
||||
},
|
||||
),
|
||||
),
|
||||
@@ -75,7 +81,11 @@ class _InfoByOrderScreenContentState extends State<InfoByOrderScreenContent> {
|
||||
leading: IconButton(
|
||||
icon: const Icon(Icons.arrow_back),
|
||||
onPressed: () {
|
||||
GoRouter.of(context).pop();
|
||||
if (GoRouter.of(context).canPop()) {
|
||||
GoRouter.of(context).pop();
|
||||
} else {
|
||||
GoRouter.of(context).go(RouteConstants.feedScreen);
|
||||
}
|
||||
},
|
||||
),
|
||||
),
|
||||
@@ -110,7 +120,11 @@ class _InfoByOrderScreenContentState extends State<InfoByOrderScreenContent> {
|
||||
leading: IconButton(
|
||||
icon: const Icon(Icons.arrow_back),
|
||||
onPressed: () {
|
||||
GoRouter.of(context).pop();
|
||||
if (GoRouter.of(context).canPop()) {
|
||||
GoRouter.of(context).pop();
|
||||
} else {
|
||||
GoRouter.of(context).go(RouteConstants.feedScreen);
|
||||
}
|
||||
},
|
||||
),
|
||||
),
|
||||
@@ -134,7 +148,7 @@ class _InfoByOrderScreenContentState extends State<InfoByOrderScreenContent> {
|
||||
const SizedBox(height: 8),
|
||||
OptionWidget(option: chosenOption, disableDuration: true, duration: plan.plan.duration),
|
||||
const SizedBox(height: 8),
|
||||
PlanState(state: plan.chosenPlanState, hasPersonalDiet: chosenOption?.hasPersonalDiet ?? false,),
|
||||
PlanState(state: plan.chosenPlanState, hasPersonalDiet: chosenOption?.hasPersonalDiet ?? false),
|
||||
const SizedBox(height: 20),
|
||||
if (widget.successfulPayment == null)
|
||||
CustomOutlinedButton(
|
||||
|
||||
@@ -4,6 +4,7 @@ import 'package:eatvio_app/features/diets/repositories/diet_repository.dart';
|
||||
import 'package:eatvio_app/features/personal_diet_suggestion/cubit/personal_diet_suggestion_state.dart';
|
||||
import 'package:eatvio_app/features/personal_diet_suggestion/repository/personal_diet_suggestion_repository.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:eatvio_app/core/error_reporting/report_from.dart';
|
||||
|
||||
class PersonalDietSuggestionCubit extends Cubit<PersonalDietSuggestionState> {
|
||||
final DietRepository dietRepository;
|
||||
@@ -17,6 +18,7 @@ class PersonalDietSuggestionCubit extends Cubit<PersonalDietSuggestionState> {
|
||||
final diet = await dietRepository.getDiet(dietId);
|
||||
emit(state.copyWith(isLoading: false, dietName: diet.name));
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
log(e.toString(), stackTrace: st);
|
||||
emit(state.copyWith(isLoading: false, error: e.toString()));
|
||||
}
|
||||
@@ -36,6 +38,7 @@ class PersonalDietSuggestionCubit extends Cubit<PersonalDietSuggestionState> {
|
||||
consultationsWithoutDiet: consultationWithoutDiet,
|
||||
));
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
log(e.toString(), stackTrace: st);
|
||||
emit(state.copyWith(isLoading: false, error: e.toString()));
|
||||
}
|
||||
@@ -48,6 +51,7 @@ class PersonalDietSuggestionCubit extends Cubit<PersonalDietSuggestionState> {
|
||||
await personalDietSuggestionService.attachPersonalDiet(consultationId: consultationId, dietId: dietId);
|
||||
return true;
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
log(e.toString(), stackTrace: st);
|
||||
return false;
|
||||
}
|
||||
@@ -60,6 +64,7 @@ class PersonalDietSuggestionCubit extends Cubit<PersonalDietSuggestionState> {
|
||||
await personalDietSuggestionService.reattachPersonalDiet(consultationId: consultationId, dietId: dietId);
|
||||
return true;
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
log(e.toString(), stackTrace: st);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import 'package:eatvio_app/features/consultations/models/consultation_model.dart';
|
||||
import 'package:eatvio_app/features/personal_diet_suggestion/services/personal_diet_suggestion_service.dart';
|
||||
import 'package:sentry_flutter/sentry_flutter.dart';
|
||||
|
||||
class PersonalDietSuggestionRepository {
|
||||
final PersonalDietSuggestionService personalDietSuggestionService;
|
||||
@@ -8,29 +7,17 @@ class PersonalDietSuggestionRepository {
|
||||
PersonalDietSuggestionRepository({required this.personalDietSuggestionService});
|
||||
|
||||
Future<List<ConsultationModel>> getConsultationWithPersonalDiets() async{
|
||||
try {
|
||||
return (await personalDietSuggestionService.getConsultationWithPersonalDiets()).data;
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
}
|
||||
return (await personalDietSuggestionService.getConsultationWithPersonalDiets()).data;
|
||||
|
||||
}
|
||||
|
||||
Future<void> attachPersonalDiet({required int consultationId, required int dietId}) async {
|
||||
try {
|
||||
return personalDietSuggestionService.attachPersonalDiet(consultationId: consultationId, dietId: dietId);
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
}
|
||||
return personalDietSuggestionService.attachPersonalDiet(consultationId: consultationId, dietId: dietId);
|
||||
|
||||
}
|
||||
|
||||
Future<void> reattachPersonalDiet({required int consultationId, required int dietId}) async {
|
||||
try {
|
||||
return await personalDietSuggestionService.reattachPersonalDiet(consultationId: consultationId, dietId: dietId);
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
}
|
||||
return await personalDietSuggestionService.reattachPersonalDiet(consultationId: consultationId, dietId: dietId);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ import 'package:eatvio_app/features/plans/models/chosen_plan_model.dart';
|
||||
import 'package:eatvio_app/features/plans/presentation/cubit/about_plan_state.dart';
|
||||
import 'package:eatvio_app/features/plans/repositories/plan_repository.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:eatvio_app/core/error_reporting/report_from.dart';
|
||||
|
||||
class AboutPlanCubit extends Cubit<AboutPlanState> {
|
||||
final PlanRepository planRepository;
|
||||
@@ -21,6 +22,7 @@ class AboutPlanCubit extends Cubit<AboutPlanState> {
|
||||
}
|
||||
emit(state.copyWith(planModel: plan, error: null));
|
||||
} catch (e, stackTrace) {
|
||||
await reportFrom(e, stackTrace, this);
|
||||
log(e.toString(), stackTrace: stackTrace);
|
||||
emit(state.copyWith(error: e.toString(), isLoading: false));
|
||||
}
|
||||
@@ -32,6 +34,7 @@ class AboutPlanCubit extends Cubit<AboutPlanState> {
|
||||
final plan = await planRepository.getPlan(slug);
|
||||
emit(state.copyWith(planModel: plan, error: null, isLoading: false));
|
||||
} catch (e, stackTrace) {
|
||||
await reportFrom(e, stackTrace, this);
|
||||
log(e.toString(), stackTrace: stackTrace);
|
||||
emit(state.copyWith(error: e.toString(), isLoading: false));
|
||||
}
|
||||
@@ -59,7 +62,8 @@ class AboutPlanCubit extends Cubit<AboutPlanState> {
|
||||
EasyDebounce.debounce('like_plan_$slug', const Duration(seconds: 1), () async {
|
||||
try {
|
||||
await planRepository.likePlan(slug);
|
||||
} catch (e) {
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
log(e.toString());
|
||||
if (index != null) {
|
||||
planRepository.emitLikesStateToFeed(LikesState(wasLikedByMe: currentPlan.wasLikedByMe, totalLikes: currentPlan.totalLikes, index: index));
|
||||
@@ -80,7 +84,8 @@ class AboutPlanCubit extends Cubit<AboutPlanState> {
|
||||
EasyDebounce.debounce('add_or_remove_plan_to_favorites', const Duration(seconds: 1), () async {
|
||||
try {
|
||||
await planRepository.addToFavorite(slug);
|
||||
} catch (e) {
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
log(e.toString());
|
||||
showErrorToast('Произошла ошибка. Попробуйте ещё раз через некоторое время');
|
||||
if (index != null) {
|
||||
@@ -102,7 +107,8 @@ class AboutPlanCubit extends Cubit<AboutPlanState> {
|
||||
EasyDebounce.debounce('add_or_remove_plan_to_favorites', const Duration(seconds: 1), () async {
|
||||
try {
|
||||
await planRepository.removeFromFavorite(slug);
|
||||
} catch (e) {
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
log(e.toString());
|
||||
showErrorToast('Произошла ошибка. Попробуйте ещё раз через некоторое время');
|
||||
if (index != null) {
|
||||
@@ -123,11 +129,13 @@ class AboutPlanCubit extends Cubit<AboutPlanState> {
|
||||
return (await planRepository.chosePlan(slug, body), null);
|
||||
}
|
||||
} on DioException catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
if (e.response?.statusCode == 400) {
|
||||
return (null, 'hasPlan');
|
||||
}
|
||||
log(e.toString(), stackTrace: st);
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
log(e.toString(), stackTrace: st);
|
||||
}
|
||||
return (null, '');
|
||||
|
||||
@@ -3,7 +3,6 @@ import 'package:eatvio_app/features/diets/repositories/diet_repository.dart';
|
||||
import 'package:eatvio_app/features/feed/models/plan_pagination_model.dart';
|
||||
import 'package:eatvio_app/features/plans/models/chosen_plan_model.dart';
|
||||
import 'package:eatvio_app/features/plans/services/plan_service.dart';
|
||||
import 'package:sentry_flutter/sentry_flutter.dart';
|
||||
|
||||
class PlanRepository {
|
||||
final PlanService planService;
|
||||
@@ -18,48 +17,28 @@ class PlanRepository {
|
||||
Stream get planCommentsState => _planCommentsStateStreamController.stream;
|
||||
|
||||
Future<PlanModel> getPlan(String slug) async {
|
||||
try {
|
||||
return planService.getPlan(slug);
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
}
|
||||
return planService.getPlan(slug);
|
||||
|
||||
}
|
||||
|
||||
Future<void> likePlan(String slug) async {
|
||||
try {
|
||||
await planService.likePlan(slug: slug);
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
}
|
||||
await planService.likePlan(slug: slug);
|
||||
|
||||
}
|
||||
|
||||
Future<void> addToFavorite(String slug) async {
|
||||
try {
|
||||
await planService.addToFavorite(slug: slug);
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
}
|
||||
await planService.addToFavorite(slug: slug);
|
||||
|
||||
}
|
||||
|
||||
Future<void> removeFromFavorite(String slug) async {
|
||||
try {
|
||||
await planService.removeFromFavorite(slug: slug);
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
}
|
||||
await planService.removeFromFavorite(slug: slug);
|
||||
|
||||
}
|
||||
|
||||
Future<ChosenPlanModel> chosePlan(String slug, Map<String, dynamic> option ) async {
|
||||
try {
|
||||
return await planService.chosePlan(slug: slug, option: option);
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
}
|
||||
return await planService.chosePlan(slug: slug, option: option);
|
||||
|
||||
}
|
||||
|
||||
void emitLikesStateToFeed(LikesState state) => _planLikeStateStreamController.add(state);
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import 'package:eatvio_app/features/feed/models/plan_pagination_model.dart';
|
||||
import 'package:eatvio_app/features/plans/services/plans_service.dart';
|
||||
import 'package:sentry_flutter/sentry_flutter.dart';
|
||||
|
||||
class PlansRepository {
|
||||
final PlansService plansService;
|
||||
@@ -8,12 +7,8 @@ class PlansRepository {
|
||||
PlansRepository({required this.plansService});
|
||||
|
||||
Future<List<PlanModel>> getPlansBySlug(String slug) async {
|
||||
try {
|
||||
final plans = (await plansService.getPlansBySlug(author: slug)).data;
|
||||
return plans.where((plan) => plan.state == 'active').toList();
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
}
|
||||
final plans = (await plansService.getPlansBySlug(author: slug)).data;
|
||||
return plans.where((plan) => plan.state == 'active').toList();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ import 'dart:developer';
|
||||
import 'package:eatvio_app/features/plans/repositories/plans_repository.dart';
|
||||
import 'package:eatvio_app/features/profile/presentation/bloc/plans_cubit/plans_state.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:eatvio_app/core/error_reporting/report_from.dart';
|
||||
|
||||
class PlansCubit extends Cubit<PlansState> {
|
||||
final PlansRepository plansRepository;
|
||||
@@ -15,7 +16,8 @@ class PlansCubit extends Cubit<PlansState> {
|
||||
emit(const PlansState.loading());
|
||||
try {
|
||||
emit(PlansState.loaded(plansList: await plansRepository.getPlansBySlug(slug)));
|
||||
} catch (e) {
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
log(e.toString());
|
||||
emit(PlansState.error(errorMessage: e.toString()));
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ import 'package:eatvio_app/features/feed/models/feed_blog_post_model.dart';
|
||||
import 'package:eatvio_app/features/profile/presentation/bloc/profile_cubit/profile_state.dart';
|
||||
import 'package:eatvio_app/features/profile/repositories/profile_repository.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:eatvio_app/core/error_reporting/report_from.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
|
||||
class ProfileCubit extends Cubit<ProfileState> {
|
||||
@@ -41,9 +42,9 @@ class ProfileCubit extends Cubit<ProfileState> {
|
||||
certPhotos: certPhotos,
|
||||
),
|
||||
);
|
||||
} catch (e) {
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
emit(ProfileState.error(errorMessage: e.toString()));
|
||||
rethrow;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -67,6 +68,7 @@ class ProfileCubit extends Cubit<ProfileState> {
|
||||
),
|
||||
);
|
||||
} catch (e, stackTrace) {
|
||||
await reportFrom(e, stackTrace, this);
|
||||
log(e.toString(), stackTrace: stackTrace);
|
||||
emit(ProfileState.error(errorMessage: e.toString()));
|
||||
}
|
||||
@@ -101,7 +103,8 @@ class ProfileCubit extends Cubit<ProfileState> {
|
||||
hipCircumference: hipCircumference,
|
||||
);
|
||||
await getMyProfile(period: _currentPeriod);
|
||||
} catch (e) {
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
emit(ProfileState.error(errorMessage: e.toString()));
|
||||
}
|
||||
}
|
||||
@@ -110,7 +113,8 @@ class ProfileCubit extends Cubit<ProfileState> {
|
||||
try {
|
||||
await profileRepository.addWeight(weight: weight);
|
||||
await getMyProfile(period: _currentPeriod);
|
||||
} catch (e) {
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
emit(ProfileState.error(errorMessage: e.toString()));
|
||||
}
|
||||
}
|
||||
@@ -121,27 +125,37 @@ class ProfileCubit extends Cubit<ProfileState> {
|
||||
final userProfile = await profileRepository.getProfileBySlug(slug);
|
||||
if (chatIdOrError == '404') {
|
||||
AppRouter.navigatorKey.currentContext?.pushNamed('emptyChatScreen', extra: userProfile);
|
||||
} else if (chatIdOrError == 'error') {
|
||||
showErrorToast('Ошибка создания чата');
|
||||
} else {
|
||||
AppRouter.navigatorKey.currentContext?.pushNamed('chatScreen', extra: {'uuid': chatIdOrError});
|
||||
return chatIdOrError;
|
||||
}
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
log(e.toString(), stackTrace: st);
|
||||
showErrorToast('Ошибка создания чата');
|
||||
return '';
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
Future<void> uploadPhoto(File file) async {
|
||||
await profileRepository.uploadPhoto(await ImageCompressUtility.compressFile(file));
|
||||
return await getMyProfile();
|
||||
try {
|
||||
await profileRepository.uploadPhoto(await ImageCompressUtility.compressFile(file));
|
||||
await getMyProfile();
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
emit(ProfileState.error(errorMessage: e.toString()));
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> deletePhoto() async {
|
||||
await profileRepository.deletePhoto();
|
||||
return await getMyProfile();
|
||||
try {
|
||||
await profileRepository.deletePhoto();
|
||||
await getMyProfile();
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
emit(ProfileState.error(errorMessage: e.toString()));
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> hideCertPhoto(int id) async {
|
||||
@@ -153,7 +167,8 @@ class ProfileCubit extends Cubit<ProfileState> {
|
||||
if (currentState is ProfileStateLoaded) {
|
||||
emit(currentState.copyWith(certPhotos: certPhotos));
|
||||
}
|
||||
} catch (e) {
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
log(e.toString());
|
||||
}
|
||||
}
|
||||
@@ -167,7 +182,8 @@ class ProfileCubit extends Cubit<ProfileState> {
|
||||
if (currentState is ProfileStateLoaded) {
|
||||
emit(currentState.copyWith(certPhotos: certPhotos));
|
||||
}
|
||||
} catch (e) {
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
log(e.toString());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import 'package:eatvio_app/features/profile/presentation/bloc/sub_cubit/sub_state.dart';
|
||||
import 'package:eatvio_app/features/profile/repositories/profile_repository.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:eatvio_app/core/error_reporting/report_from.dart';
|
||||
|
||||
class SubCubit extends Cubit<SubState> {
|
||||
final ProfileRepository profileRepository;
|
||||
@@ -16,7 +17,8 @@ class SubCubit extends Cubit<SubState> {
|
||||
return;
|
||||
}
|
||||
emit(SubState.loaded(subList: await profileRepository.getSubscriptionsBySlug(slug, query)));
|
||||
} catch (e) {
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
emit(SubState.error(errorMessage: e.toString()));
|
||||
}
|
||||
}
|
||||
@@ -30,16 +32,25 @@ class SubCubit extends Cubit<SubState> {
|
||||
return;
|
||||
}
|
||||
emit(SubState.loaded(subList: await profileRepository.getSubscribersBySlug(slug, query)));
|
||||
} catch (e) {
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
emit(SubState.error(errorMessage: e.toString()));
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> subscribe(String slug) async {
|
||||
return await profileRepository.subscribe(slug);
|
||||
try {
|
||||
await profileRepository.subscribe(slug);
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> unsubscribe(String slug) async {
|
||||
return await profileRepository.unsubscribe(slug);
|
||||
try {
|
||||
await profileRepository.unsubscribe(slug);
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,7 +9,6 @@ import 'package:eatvio_app/features/profile/models/profile_model.dart';
|
||||
import 'package:eatvio_app/features/profile/models/sub_model.dart';
|
||||
import 'package:eatvio_app/features/profile/models/weight_model.dart';
|
||||
import 'package:eatvio_app/features/profile/services/profile_service.dart';
|
||||
import 'package:sentry_flutter/sentry_flutter.dart';
|
||||
|
||||
class ProfileRepository {
|
||||
final ProfileService profileService;
|
||||
@@ -17,210 +16,101 @@ class ProfileRepository {
|
||||
ProfileRepository({required this.profileService});
|
||||
|
||||
Future<ProfileModel> getProfileBySlug(String slug) async {
|
||||
try {
|
||||
return await profileService.getProfileBySlug(slug: slug);
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
}
|
||||
return profileService.getProfileBySlug(slug: slug);
|
||||
}
|
||||
|
||||
Future<ProfileDetailsModel> getProfileDetailsBySlug(String slug) async {
|
||||
try {
|
||||
return await profileService.getProfileDetailsBySlug(slug: slug);
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
}
|
||||
return profileService.getProfileDetailsBySlug(slug: slug);
|
||||
}
|
||||
|
||||
Future<ProfileModel> getMyProfile() async {
|
||||
try {
|
||||
return await profileService.getMyProfile();
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
}
|
||||
return profileService.getMyProfile();
|
||||
}
|
||||
|
||||
Future<ProfileDetailsModel> getMyProfileDetails() async {
|
||||
try {
|
||||
return await profileService.getMyProfileDetails();
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
}
|
||||
return profileService.getMyProfileDetails();
|
||||
}
|
||||
|
||||
Future<void> addCircumference({required int chestCircumference, required int waistCircumference, required int hipCircumference}) async {
|
||||
try {
|
||||
return (await profileService.addCircumference(
|
||||
chestCircumference: chestCircumference,
|
||||
waistCircumference: waistCircumference,
|
||||
hipCircumference: hipCircumference,
|
||||
));
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
}
|
||||
return profileService.addCircumference(
|
||||
chestCircumference: chestCircumference,
|
||||
waistCircumference: waistCircumference,
|
||||
hipCircumference: hipCircumference,
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> addWeight({required double weight}) async {
|
||||
try {
|
||||
return (await profileService.addWeight(weight: weight));
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
}
|
||||
return profileService.addWeight(weight: weight);
|
||||
}
|
||||
|
||||
Future<List<FeedBlogPostModel>> getBlogPostsByAuthorSlug({required String slug}) async {
|
||||
try {
|
||||
return (await profileService.getBlogPostByAuthorSlug(slug: slug));
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
}
|
||||
return profileService.getBlogPostByAuthorSlug(slug: slug);
|
||||
}
|
||||
|
||||
Future<List<WeightModel>> getWeight({required String period, String? slug}) async {
|
||||
try {
|
||||
if (slug != null) {
|
||||
return (await profileService.getWeightBySlug(period: period, slug: slug));
|
||||
} else {
|
||||
return (await profileService.getWeight(period: period));
|
||||
}
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
if (slug != null) {
|
||||
return profileService.getWeightBySlug(period: period, slug: slug);
|
||||
}
|
||||
return profileService.getWeight(period: period);
|
||||
}
|
||||
|
||||
Future<List<CircumferenceModel>> getCircumferences({required String period, String? slug}) async {
|
||||
try {
|
||||
if (slug != null) {
|
||||
return (await profileService.getCircumferencesBySlug(period: period, slug: slug));
|
||||
} else {
|
||||
return (await profileService.getCircumferences(period: period));
|
||||
}
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
if (slug != null) {
|
||||
return profileService.getCircumferencesBySlug(period: period, slug: slug);
|
||||
}
|
||||
return profileService.getCircumferences(period: period);
|
||||
}
|
||||
|
||||
Future<List<SubModel>> getSubscribersBySlug(String slug, [String? query]) async {
|
||||
try {
|
||||
return (await profileService.getSubscribers(slug: slug, query: query)).data;
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
}
|
||||
return (await profileService.getSubscribers(slug: slug, query: query)).data;
|
||||
}
|
||||
|
||||
Future<List<SubModel>> getSubscriptionsBySlug(String slug, [String? query]) async {
|
||||
try {
|
||||
return (await profileService.getSubscriptions(slug: slug, query: query)).data;
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
}
|
||||
return (await profileService.getSubscriptions(slug: slug, query: query)).data;
|
||||
}
|
||||
|
||||
Future<void> subscribe(String slug) async {
|
||||
try {
|
||||
return await profileService.subscribe(slug: slug);
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
}
|
||||
return profileService.subscribe(slug: slug);
|
||||
}
|
||||
|
||||
Future<void> unsubscribe(String slug) async {
|
||||
try {
|
||||
return await profileService.unsubscribe(slug: slug);
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
}
|
||||
return profileService.unsubscribe(slug: slug);
|
||||
}
|
||||
|
||||
Future<void> uploadPhoto(File file) async {
|
||||
try {
|
||||
return await profileService.uploadPhoto(photo: file);
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
}
|
||||
return profileService.uploadPhoto(photo: file);
|
||||
}
|
||||
|
||||
Future<void> deletePhoto() async {
|
||||
try {
|
||||
return await profileService.deletePhoto();
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
}
|
||||
return profileService.deletePhoto();
|
||||
}
|
||||
|
||||
Future<List<ChosenDietModel>> getChosenDiets() async {
|
||||
try {
|
||||
return (await profileService.getChosenDiets()).diets;
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
}
|
||||
return (await profileService.getChosenDiets()).diets;
|
||||
}
|
||||
|
||||
Future<String> getPassKey({required String routeName, Map<String, dynamic>? routeParams}) async {
|
||||
try {
|
||||
return (await profileService.getPassKey(
|
||||
json: PassKeyParams(routeName: routeName, routeParams: routeParams),
|
||||
)).data['key_is']!;
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
}
|
||||
return (await profileService.getPassKey(
|
||||
json: PassKeyParams(routeName: routeName, routeParams: routeParams),
|
||||
)).data['key_is']!;
|
||||
}
|
||||
|
||||
Future<String> getMyPhone() async {
|
||||
try {
|
||||
return (jsonDecode(await profileService.getMyPhone())['phone']);
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
}
|
||||
return (jsonDecode(await profileService.getMyPhone())['phone']);
|
||||
}
|
||||
|
||||
Future<void> sendEmailCode({String? newEmail}) async {
|
||||
try {
|
||||
if (newEmail != null) {
|
||||
return await profileService.sendEmailCode(data: {'new_email': newEmail});
|
||||
} else {
|
||||
return await profileService.sendEmailCode();
|
||||
}
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
if (newEmail != null) {
|
||||
return profileService.sendEmailCode(data: {'new_email': newEmail});
|
||||
}
|
||||
return profileService.sendEmailCode();
|
||||
}
|
||||
|
||||
Future<bool> tryVerifyEmailByCode(String code) async {
|
||||
try {
|
||||
await profileService.tryVerifyEmailByCode(code: "{\"code\": \"$code\"}");
|
||||
return true;
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
return false;
|
||||
}
|
||||
Future<void> tryVerifyEmailByCode(String code) async {
|
||||
await profileService.tryVerifyEmailByCode(code: "{\"code\": \"$code\"}");
|
||||
}
|
||||
|
||||
Future<void> deleteAccount() async {
|
||||
try {
|
||||
await profileService.deleteAccount();
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
}
|
||||
await profileService.deleteAccount();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ import 'package:eatvio_app/features/recipe/repositories/about_recipe_repository.
|
||||
import 'package:eatvio_app/features/profile/repositories/profile_repository.dart';
|
||||
import 'package:eatvio_app/features/recipe/presentation/cubit/about_recipe_state.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:eatvio_app/core/error_reporting/report_from.dart';
|
||||
|
||||
class AboutRecipeCubit extends Cubit<AboutRecipeState> {
|
||||
AboutRecipeCubit({required this.recipeRepository, required this.profileRepository}) : super(const AboutRecipeState.initial());
|
||||
@@ -23,7 +24,8 @@ class AboutRecipeCubit extends Cubit<AboutRecipeState> {
|
||||
recipeRepository.emitCommentsStateToFeed(CommentsState(index: index, totalComments: recipe.commentsCount));
|
||||
}
|
||||
emit(AboutRecipeState.loaded(recipe: recipe));
|
||||
} catch (e) {
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
log(e.toString());
|
||||
emit(AboutRecipeState.error(message: e.toString()));
|
||||
}
|
||||
@@ -37,7 +39,8 @@ class AboutRecipeCubit extends Cubit<AboutRecipeState> {
|
||||
recipeRepository.emitCommentsStateToFeed(CommentsState(index: index, totalComments: recipe.commentsCount));
|
||||
}
|
||||
emit(AboutRecipeState.loaded(recipe: recipe));
|
||||
} catch (e) {
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
log(e.toString());
|
||||
emit(AboutRecipeState.error(message: e.toString()));
|
||||
}
|
||||
@@ -76,7 +79,8 @@ class AboutRecipeCubit extends Cubit<AboutRecipeState> {
|
||||
() async {
|
||||
try {
|
||||
await recipeRepository.likeRecipe(id);
|
||||
} catch (e) {
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
log(e.toString());
|
||||
if (recipeIndexInFeed != null) {
|
||||
recipeRepository
|
||||
@@ -107,7 +111,8 @@ class AboutRecipeCubit extends Cubit<AboutRecipeState> {
|
||||
() async {
|
||||
try {
|
||||
await recipeRepository.addToFavorite(id);
|
||||
} catch (e) {
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
log(e.toString());
|
||||
showErrorToast('Произошла ошибка. Попробуйте ещё раз через некоторое время');
|
||||
if (recipeIndex != null) {
|
||||
@@ -138,7 +143,8 @@ class AboutRecipeCubit extends Cubit<AboutRecipeState> {
|
||||
() async {
|
||||
try {
|
||||
await recipeRepository.removeFromFavorite(id);
|
||||
} catch (e) {
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
log(e.toString());
|
||||
showErrorToast('Произошла ошибка. Попробуйте ещё раз через некоторое время');
|
||||
if (recipeIndex != null) {
|
||||
|
||||
@@ -8,7 +8,7 @@ import 'package:eatvio_app/features/recipe/presentation/cubit/my_recipes_cubit/m
|
||||
import 'package:eatvio_app/features/recipe/repositories/about_recipe_repository.dart';
|
||||
import 'package:eatvio_app/features/recipe/repositories/my_recipes_repository.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:sentry_flutter/sentry_flutter.dart';
|
||||
import 'package:eatvio_app/core/error_reporting/report_from.dart';
|
||||
|
||||
class MyRecipesCubit extends Cubit<MyRecipesState> {
|
||||
final MyRecipesRepository myRecipesRepository;
|
||||
@@ -31,7 +31,8 @@ class MyRecipesCubit extends Cubit<MyRecipesState> {
|
||||
final myRecipes = await myRecipesRepository.getMyRecipes();
|
||||
final List<MyRecipeModel> activeRecipes = myRecipes.where((recipe) => recipe.state == active).toList();
|
||||
emit(MyRecipesState.loaded(recipes: activeRecipes, selectedState: active));
|
||||
} catch (e) {
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
emit(const MyRecipesState.error());
|
||||
}
|
||||
}
|
||||
@@ -42,7 +43,8 @@ class MyRecipesCubit extends Cubit<MyRecipesState> {
|
||||
final myRecipes = await myRecipesRepository.getMyRecipes();
|
||||
final List<MyRecipeModel> activeRecipes = myRecipes.where((recipe) => recipe.state == active).toList();
|
||||
emit(MyRecipesState.loaded(recipes: activeRecipes, selectedState: active));
|
||||
} catch (e) {
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
emit(const MyRecipesState.error());
|
||||
}
|
||||
}
|
||||
@@ -53,7 +55,8 @@ class MyRecipesCubit extends Cubit<MyRecipesState> {
|
||||
final myRecipes = await myRecipesRepository.getMyRecipes();
|
||||
final List<MyRecipeModel> archivedRecipes = myRecipes.where((recipe) => recipe.state == archived).toList();
|
||||
emit(MyRecipesState.loaded(recipes: archivedRecipes, selectedState: archived));
|
||||
} catch (e) {
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
emit(const MyRecipesState.error());
|
||||
}
|
||||
}
|
||||
@@ -64,13 +67,19 @@ class MyRecipesCubit extends Cubit<MyRecipesState> {
|
||||
final myRecipes = await myRecipesRepository.getMyRecipes();
|
||||
final List<MyRecipeModel> draftedRecipes = myRecipes.where((recipe) => recipe.state == drafted).toList();
|
||||
emit(MyRecipesState.loaded(recipes: draftedRecipes, selectedState: drafted));
|
||||
} catch (e) {
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
emit(const MyRecipesState.error());
|
||||
}
|
||||
}
|
||||
|
||||
Future<Recipe> getRecipeById(String slug) async {
|
||||
return await aboutRecipeRepository.getRecipe(slug);
|
||||
Future<Recipe?> getRecipeById(String slug) async {
|
||||
try {
|
||||
return await aboutRecipeRepository.getRecipe(slug);
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// Attempts to publish a drafted recipe
|
||||
@@ -81,10 +90,9 @@ class MyRecipesCubit extends Cubit<MyRecipesState> {
|
||||
await recipeRepository.publishRecipe(recipe, true, slug);
|
||||
return true;
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
if (e is DioException && e.response?.statusCode == 422) {
|
||||
log('Validation failed for publishing draft: \${e.response?.data}');
|
||||
} else {
|
||||
await Sentry.captureException(e, stackTrace: st);
|
||||
log('Validation failed for publishing draft: ${e.response?.data}');
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -96,8 +104,8 @@ class MyRecipesCubit extends Cubit<MyRecipesState> {
|
||||
await recipeRepository.draftExistingRecipe(id);
|
||||
return true;
|
||||
} catch (e, st) {
|
||||
log('Failed to draft recipe: \$e');
|
||||
await Sentry.captureException(e, stackTrace: st);
|
||||
await reportFrom(e, st, this);
|
||||
log('Failed to draft recipe: $e');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -155,6 +155,10 @@ class _MyRecipeWidgetState extends State<MyRecipeWidget> {
|
||||
final fullRecipe = await context.read<MyRecipesCubit>().getRecipeById(widget.recipe.slug);
|
||||
if (context.mounted) {
|
||||
Navigator.pop(context); // close dialog
|
||||
if (fullRecipe == null) {
|
||||
showErrorToast('Не удалось загрузить рецепт');
|
||||
return;
|
||||
}
|
||||
final result = await context.push(RecipeCreateScreen.path, extra: fullRecipe);
|
||||
if (!context.mounted) return;
|
||||
if (result == MyRecipesCubit.drafted) {
|
||||
@@ -226,11 +230,16 @@ class _MyRecipeWidgetState extends State<MyRecipeWidget> {
|
||||
builder: (context) => const Center(child: CircularProgressIndicator()),
|
||||
);
|
||||
final fullRecipe = await context.read<MyRecipesCubit>().getRecipeById(widget.recipe.slug);
|
||||
if (!context.mounted) return;
|
||||
Navigator.pop(context);
|
||||
if (fullRecipe == null) {
|
||||
showErrorToast('Не удалось загрузить рецепт');
|
||||
return;
|
||||
}
|
||||
final createCubit = sl<CreateRecipeCubit>();
|
||||
await createCubit.recipeToEntity(fullRecipe);
|
||||
|
||||
if (context.mounted) {
|
||||
Navigator.pop(context);
|
||||
if (createCubit.validateAll()) {
|
||||
final success = await createCubit.publishRecipe(true, widget.recipe.slug);
|
||||
if (success && context.mounted) {
|
||||
|
||||
@@ -3,7 +3,6 @@ import 'dart:async';
|
||||
import 'package:eatvio_app/features/diets/repositories/diet_repository.dart';
|
||||
import 'package:eatvio_app/features/feed/models/recipes_model.dart';
|
||||
import 'package:eatvio_app/features/recipe/services/about_recipe_service.dart';
|
||||
import 'package:sentry_flutter/sentry_flutter.dart';
|
||||
|
||||
class AboutRecipeRepository {
|
||||
final AboutRecipeService recipeService;
|
||||
@@ -17,48 +16,28 @@ class AboutRecipeRepository {
|
||||
AboutRecipeRepository({required this.recipeService});
|
||||
|
||||
Future<Recipe> getRecipe(String recipeID) async {
|
||||
try {
|
||||
return await recipeService.getRecipe(recipeID);
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
}
|
||||
return await recipeService.getRecipe(recipeID);
|
||||
|
||||
}
|
||||
|
||||
Future<void> likeRecipe(String slug) async {
|
||||
try {
|
||||
await recipeService.likeRecipe(slug: slug);
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
}
|
||||
await recipeService.likeRecipe(slug: slug);
|
||||
|
||||
}
|
||||
|
||||
Future<void> addToFavorite(String slug) async {
|
||||
try {
|
||||
await recipeService.addToFavorite(slug: slug);
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
}
|
||||
await recipeService.addToFavorite(slug: slug);
|
||||
|
||||
}
|
||||
|
||||
Future<void> removeFromFavorite(String slug) async {
|
||||
try {
|
||||
await recipeService.removeFromFavorite(slug: slug);
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
}
|
||||
await recipeService.removeFromFavorite(slug: slug);
|
||||
|
||||
}
|
||||
|
||||
Future<void> deleteRecipe(String slug) async {
|
||||
try {
|
||||
await recipeService.deleteRecipe(slug: slug);
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
}
|
||||
await recipeService.deleteRecipe(slug: slug);
|
||||
|
||||
}
|
||||
|
||||
void emitLikesStateToFeed(LikesState state) => _recipeLikeStateStreamController.add(state);
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import 'package:eatvio_app/features/recipe/models/my_recipe_model.dart';
|
||||
import 'package:eatvio_app/features/recipe/services/my_recipes_service.dart';
|
||||
import 'package:sentry_flutter/sentry_flutter.dart';
|
||||
|
||||
class MyRecipesRepository {
|
||||
final MyRecipesService myRecipesService;
|
||||
@@ -8,11 +7,7 @@ class MyRecipesRepository {
|
||||
MyRecipesRepository({required this.myRecipesService});
|
||||
|
||||
Future<List<MyRecipeModel>> getMyRecipes() async {
|
||||
try {
|
||||
return (await myRecipesService.getMyRecipes()).data;
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
}
|
||||
return (await myRecipesService.getMyRecipes()).data;
|
||||
|
||||
}
|
||||
}
|
||||
@@ -9,9 +9,11 @@ import 'package:eatvio_app/core/prefs.dart';
|
||||
import 'package:eatvio_app/core/token_storage.dart';
|
||||
import 'package:eatvio_app/features/registration/models/user_registration_model.dart';
|
||||
import 'package:eatvio_app/features/registration/presentation/bloc/registration_cubit/registration_state.dart';
|
||||
import 'package:eatvio_app/features/registration/registration_error_message.dart';
|
||||
import 'package:eatvio_app/features/registration/repositories/registration_repository.dart';
|
||||
import 'package:eatvio_app/features/registration/services/registration_analytics_service.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:eatvio_app/core/error_reporting/report_from.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
|
||||
class RegistrationCubit extends Cubit<RegistrationState> with RegistrationDateCacheMixin {
|
||||
@@ -65,9 +67,11 @@ class RegistrationCubit extends Cubit<RegistrationState> with RegistrationDateCa
|
||||
cacheRegistrationDate(DateTime.now());
|
||||
AppRouter.navigatorKey.currentContext?.replaceNamed('verifyEmailScreen');
|
||||
} catch (e, st) {
|
||||
log(e.toString(), stackTrace: st);
|
||||
RegistrationAnalyticsService.reportRegistrationError(e.toString());
|
||||
emit(RegistrationState(sheet: state.sheet, error: e.toString()));
|
||||
await reportFrom(e, st, this);
|
||||
final message = registrationErrorMessage(e);
|
||||
log(message, stackTrace: st);
|
||||
RegistrationAnalyticsService.reportRegistrationError(message);
|
||||
emit(RegistrationState(sheet: state.sheet, error: message));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -76,8 +80,9 @@ class RegistrationCubit extends Cubit<RegistrationState> with RegistrationDateCa
|
||||
final location = (await registrationRepository.getLocationsListByQuery(query));
|
||||
emit(RegistrationState(sheet: state.sheet.copyWith(responseBody: location.responseBody)));
|
||||
return location.locations;
|
||||
} catch (e) {
|
||||
rethrow;
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -86,8 +91,9 @@ class RegistrationCubit extends Cubit<RegistrationState> with RegistrationDateCa
|
||||
final location = (await registrationRepository.getLocationsListByCoordinates(latitude, longitude));
|
||||
emit(RegistrationState(sheet: state.sheet.copyWith(responseBody: location.responseBody)));
|
||||
return location.locations;
|
||||
} catch (e) {
|
||||
rethrow;
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
return [];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import 'package:eatvio_app/features/profile/repositories/profile_repository.dart
|
||||
import 'package:eatvio_app/features/registration/presentation/bloc/verify_email_cubit/verify_email_state.dart';
|
||||
import 'package:eatvio_app/features/registration/services/registration_analytics_service.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:eatvio_app/core/error_reporting/report_from.dart';
|
||||
|
||||
class VerifyEmailCubit extends Cubit<VerifyEmailState> {
|
||||
final ProfileRepository profileRepository;
|
||||
@@ -16,7 +17,8 @@ class VerifyEmailCubit extends Cubit<VerifyEmailState> {
|
||||
final profile = await profileRepository.getMyProfile();
|
||||
await profileRepository.sendEmailCode();
|
||||
emit(VerifyEmailState.loaded(email: profile.email));
|
||||
} catch (e) {
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
emit(const VerifyEmailState.error(errorMessage: 'Ошибка отправки кода.\nПовторите попытку позже'));
|
||||
}
|
||||
}
|
||||
@@ -24,18 +26,15 @@ class VerifyEmailCubit extends Cubit<VerifyEmailState> {
|
||||
Future<void> tryVerify(String code) async {
|
||||
try {
|
||||
emit(const VerifyEmailState.verifyLoading());
|
||||
final result = await profileRepository.tryVerifyEmailByCode(code);
|
||||
if (result == true) {
|
||||
emit(const VerifyEmailState.verifySuccess());
|
||||
try {
|
||||
RegistrationAnalyticsService.reportEmailVerification();
|
||||
} catch (e) {
|
||||
// Игнорируем ошибки аналитики, верификация уже успешна
|
||||
}
|
||||
} else {
|
||||
emit(const VerifyEmailState.verifyError());
|
||||
await profileRepository.tryVerifyEmailByCode(code);
|
||||
emit(const VerifyEmailState.verifySuccess());
|
||||
try {
|
||||
RegistrationAnalyticsService.reportEmailVerification();
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
}
|
||||
} catch (e) {
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
emit(const VerifyEmailState.verifyError());
|
||||
}
|
||||
}
|
||||
@@ -47,7 +46,8 @@ class VerifyEmailCubit extends Cubit<VerifyEmailState> {
|
||||
emit(const VerifyEmailState.changeEmailSuccess());
|
||||
// Обновляем email в состоянии после успешной смены
|
||||
emit(VerifyEmailState.loaded(email: newEmail));
|
||||
} catch (e) {
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
emit(const VerifyEmailState.changeEmailError());
|
||||
}
|
||||
}
|
||||
|
||||
35
lib/features/registration/registration_error_message.dart
Normal file
35
lib/features/registration/registration_error_message.dart
Normal file
@@ -0,0 +1,35 @@
|
||||
import 'package:dio/dio.dart';
|
||||
|
||||
/// Сообщение для UI / аналитики при ошибке регистрации (вызывать из кубита).
|
||||
String registrationErrorMessage(Object error) {
|
||||
if (error is String) {
|
||||
return error;
|
||||
}
|
||||
if (error is DioException && error.response?.statusCode == 422) {
|
||||
final data = error.response?.data;
|
||||
if (data is Map<String, dynamic>) {
|
||||
var errorMsg = '';
|
||||
if (data.containsKey('message')) {
|
||||
errorMsg += '${data['message']}\n';
|
||||
}
|
||||
if (data.containsKey('errors')) {
|
||||
final errors = data['errors'];
|
||||
if (errors is Map) {
|
||||
errors.forEach((key, value) {
|
||||
if (value is List && value.isNotEmpty) {
|
||||
errorMsg += '${value.join('\n')}\n';
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
if (errorMsg.isNotEmpty) {
|
||||
return errorMsg.trim();
|
||||
}
|
||||
return 'Ошибка регистрации: $data';
|
||||
}
|
||||
}
|
||||
if (error is DioException) {
|
||||
return error.message ?? error.toString();
|
||||
}
|
||||
return error.toString();
|
||||
}
|
||||
@@ -1,10 +1,9 @@
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:eatvio_app/core/locator_service.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';
|
||||
import 'package:eatvio_app/core/env_config.dart';
|
||||
import 'package:sentry_flutter/sentry_flutter.dart';
|
||||
import 'package:eatvio_app/core/locator_service.dart';
|
||||
import 'package:eatvio_app/features/registration/models/location_model.dart';
|
||||
import 'package:eatvio_app/features/registration/models/user_registration_model.dart';
|
||||
import 'package:eatvio_app/features/registration/services/registration_service.dart';
|
||||
|
||||
class RegistrationRepository {
|
||||
final RegistrationService registrationService;
|
||||
@@ -12,94 +11,36 @@ class RegistrationRepository {
|
||||
RegistrationRepository({required this.registrationService});
|
||||
|
||||
Future<String> tryRegister(UserRegistrationSheet sheet) async {
|
||||
try {
|
||||
final response = await registrationService.register(sheet: sheet.toJson());
|
||||
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, s) {
|
||||
if (e.response != null && e.response?.statusCode == 422) {
|
||||
final data = e.response?.data;
|
||||
String errorMsg = '';
|
||||
if (data is Map<String, dynamic>) {
|
||||
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';
|
||||
}
|
||||
}
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
final response = await registrationService.register(sheet: sheet.toJson());
|
||||
if (response.containsKey('token')) {
|
||||
return response['token']!;
|
||||
}
|
||||
var errorMsg = '';
|
||||
if (response.containsKey('message')) {
|
||||
errorMsg += '${response['message']}\n';
|
||||
}
|
||||
if (response.containsKey('errors')) {
|
||||
errorMsg += '${response['errors']}\n';
|
||||
}
|
||||
if (errorMsg.isNotEmpty) {
|
||||
throw errorMsg.trim();
|
||||
}
|
||||
throw 'Ошибка регистрации: $response';
|
||||
}
|
||||
|
||||
Future<LocationModel> getLocationsListByQuery(String query) async {
|
||||
try {
|
||||
return (await registrationService.getLocationsByAddress(query: query));
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
}
|
||||
return registrationService.getLocationsByAddress(query: query);
|
||||
}
|
||||
|
||||
Future<LocationModel> getLocationsListByCoordinates(String latitude, String longitude) async {
|
||||
try {
|
||||
return (await registrationService.getLocationsByCoordinate(latitude: latitude, longitude: longitude));
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
}
|
||||
return registrationService.getLocationsByCoordinate(latitude: latitude, longitude: longitude);
|
||||
}
|
||||
|
||||
Future<bool> emailIsReachable(String email) async {
|
||||
try {
|
||||
final response = await sl<Dio>().getUri(Uri.parse('${EnvConfig.emailValidationApiUrl}?email=$email'));
|
||||
if (response.data['result']['reachable'] != 'invalid') {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
return false;
|
||||
final response = await sl<Dio>().getUri(Uri.parse('${EnvConfig.emailValidationApiUrl}?email=$email'));
|
||||
if (response.data['result']['reachable'] != 'invalid') {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,267 +1,270 @@
|
||||
import 'dart:developer';
|
||||
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:eatvio_app/core/token_storage.dart';
|
||||
import 'package:eatvio_app/core/utils/date_time_utils.dart';
|
||||
import 'package:eatvio_app/core/utils/validation_utils.dart';
|
||||
import 'package:eatvio_app/features/registration_v2/cubit/registration_state.dart';
|
||||
import 'package:eatvio_app/features/registration_v2/models/registration_model.dart';
|
||||
import 'package:eatvio_app/features/registration_v2/repositories/registration_repository_v2.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:gpassword/gpassword.dart';
|
||||
|
||||
class RegistrationCubitV2 extends Cubit<RegistrationStateV2> {
|
||||
final RegistrationRepositoryV2 registrationRepository;
|
||||
RegistrationCubitV2({required this.registrationRepository}) : super(const RegistrationStateV2());
|
||||
|
||||
void setFirstName(String firstName) {
|
||||
emit(state.copyWith(firstName: firstName));
|
||||
validateFirstName();
|
||||
}
|
||||
|
||||
void setLastName(String lastName) {
|
||||
emit(state.copyWith(lastName: lastName));
|
||||
validateLastName();
|
||||
}
|
||||
|
||||
void setEmail(String email) {
|
||||
emit(state.copyWith(email: email));
|
||||
validateEmail();
|
||||
}
|
||||
|
||||
void setPhone(String phone) {
|
||||
emit(state.copyWith(phone: phone));
|
||||
validatePhone();
|
||||
}
|
||||
|
||||
void setBirthday(DateTime birthday) {
|
||||
emit(state.copyWith(birthday: birthday));
|
||||
validateBirthday();
|
||||
}
|
||||
|
||||
void setGender(String gender) {
|
||||
emit(state.copyWith(gender: gender));
|
||||
validateGender();
|
||||
}
|
||||
|
||||
void setWeight(int weight) {
|
||||
emit(state.copyWith(weight: weight));
|
||||
validateWeight();
|
||||
}
|
||||
|
||||
void setHeight(int height) {
|
||||
emit(state.copyWith(height: height));
|
||||
validateHeight();
|
||||
}
|
||||
|
||||
void setActivityCoefficient(double activityCoefficient) {
|
||||
emit(state.copyWith(activityCoefficient: activityCoefficient));
|
||||
validateActivityCoefficient();
|
||||
}
|
||||
|
||||
void setPassword(String password) {
|
||||
emit(state.copyWith(password: password));
|
||||
}
|
||||
|
||||
bool validateFirstName() {
|
||||
if (state.firstName.isEmpty) {
|
||||
emit(state.copyWith(isFirstNameValid: false));
|
||||
return false;
|
||||
}
|
||||
emit(state.copyWith(isFirstNameValid: true));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool validateLastName() {
|
||||
if (state.lastName.isEmpty) {
|
||||
emit(state.copyWith(isLastNameValid: false));
|
||||
return false;
|
||||
}
|
||||
emit(state.copyWith(isLastNameValid: true));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool validateEmail() {
|
||||
if (state.email.isEmpty) {
|
||||
emit(state.copyWith(isEmailValid: false));
|
||||
return false;
|
||||
}
|
||||
emit(state.copyWith(isEmailValid: true));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool validatePhone() {
|
||||
if (state.phone.isEmpty) {
|
||||
emit(state.copyWith(isPhoneValid: false));
|
||||
return false;
|
||||
}
|
||||
emit(state.copyWith(isPhoneValid: true));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool validateGender() {
|
||||
if (state.gender.isEmpty) {
|
||||
emit(state.copyWith(isGenderValid: false));
|
||||
return false;
|
||||
}
|
||||
emit(state.copyWith(isGenderValid: true));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool validateWeight() {
|
||||
if (state.weight == 0) {
|
||||
emit(state.copyWith(isWeightValid: false));
|
||||
return false;
|
||||
}
|
||||
emit(state.copyWith(isWeightValid: true));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool validateHeight() {
|
||||
if (state.height == 0) {
|
||||
emit(state.copyWith(isHeightValid: false));
|
||||
return false;
|
||||
}
|
||||
emit(state.copyWith(isHeightValid: true));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool validateActivityCoefficient() {
|
||||
if (state.activityCoefficient == 0) {
|
||||
emit(state.copyWith(isActivityCoefficientValid: false));
|
||||
return false;
|
||||
}
|
||||
emit(state.copyWith(isActivityCoefficientValid: true));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool validateBirthday() {
|
||||
if (state.birthday == null) {
|
||||
emit(state.copyWith(isBirthdayValid: false));
|
||||
return false;
|
||||
}
|
||||
emit(state.copyWith(isBirthdayValid: true));
|
||||
return true;
|
||||
}
|
||||
|
||||
void nextStep() {
|
||||
emit(state.copyWith(step: 1));
|
||||
}
|
||||
|
||||
void prevStep() {
|
||||
emit(state.copyWith(step: 0));
|
||||
}
|
||||
|
||||
bool validateAllFields() {
|
||||
if (!validateFirstName() ||
|
||||
!validateLastName() ||
|
||||
!validateEmail() ||
|
||||
!validatePhone() ||
|
||||
!validateGender() ||
|
||||
!validateWeight() ||
|
||||
!validateHeight() ||
|
||||
!validateActivityCoefficient() ||
|
||||
!validateBirthday()) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
Future<(bool, bool)> register() async {
|
||||
if (!validateAllFields()) {
|
||||
return (false, true);
|
||||
}
|
||||
final birthday = state.birthday?.format('yyyy-MM-dd');
|
||||
if (birthday == null) {
|
||||
validateBirthday();
|
||||
return (false, true);
|
||||
}
|
||||
final password = await _generatePassword();
|
||||
final registrationModel = RegistrationModel(
|
||||
firstName: state.firstName,
|
||||
lastName: state.lastName,
|
||||
email: state.email,
|
||||
phone: ValidationUtils.normalizePhone(state.phone),
|
||||
gender: state.gender,
|
||||
password: password,
|
||||
confirmPassword: password,
|
||||
weight: state.weight,
|
||||
height: state.height,
|
||||
activityCoefficient: state.activityCoefficient,
|
||||
birthday: birthday,
|
||||
);
|
||||
bool didApiComplainOnValidation = false;
|
||||
String errorMessage = '';
|
||||
try {
|
||||
final token = await registrationRepository.register(registrationModel: registrationModel);
|
||||
if (token != null) {
|
||||
TokenStorage.saveTokenInStorage(token);
|
||||
emit(state.copyWith(registrationError: null));
|
||||
return (true, false);
|
||||
}
|
||||
} on DioException catch (e) {
|
||||
final errors = e.response?.data['errors'] as Map<String, dynamic>?;
|
||||
final emailErrors = errors?['email'] as List<dynamic>?;
|
||||
final phoneErrors = errors?['phone'] as List<dynamic>?;
|
||||
final dateOfBirth = errors?['date_of_birth'] as List<dynamic>?;
|
||||
|
||||
// Собираем все ошибки для отображения в диалоге
|
||||
List<String> allErrors = [];
|
||||
|
||||
if (emailErrors != null && emailErrors.isNotEmpty) {
|
||||
for (var error in emailErrors) {
|
||||
allErrors.add(error.toString());
|
||||
if (error.toString() == 'Некорректный формат email') {
|
||||
emit(state.copyWith(isEmailValid: false, emailDisplayError: 'Некорректный формат email'));
|
||||
didApiComplainOnValidation = true;
|
||||
}
|
||||
if (error.toString() == 'Такой Эл. почта уже существует.') {
|
||||
emit(state.copyWith(isEmailValid: false, emailDisplayError: 'Такая Эл. почта уже существует.'));
|
||||
didApiComplainOnValidation = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (phoneErrors != null && phoneErrors.isNotEmpty) {
|
||||
for (var error in phoneErrors) {
|
||||
allErrors.add(error.toString());
|
||||
if (error.toString() == 'Такой phone уже существует.') {
|
||||
emit(state.copyWith(isPhoneValid: false, phoneDisplayError: 'Такой номер телефона уже существует.'));
|
||||
didApiComplainOnValidation = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (dateOfBirth != null && dateOfBirth.isNotEmpty) {
|
||||
for (var error in dateOfBirth) {
|
||||
allErrors.add(error.toString());
|
||||
if (error.toString() == 'Некорректный формат даты рождения') {
|
||||
emit(state.copyWith(isBirthdayValid: false, dateOfBirthDisplayError: 'Некорректный формат даты рождения'));
|
||||
didApiComplainOnValidation = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Сохраняем все ошибки для отображения в диалоге
|
||||
if (allErrors.isNotEmpty) {
|
||||
errorMessage = allErrors.join('\n');
|
||||
emit(state.copyWith(registrationError: errorMessage));
|
||||
} else {
|
||||
// Если нет конкретных ошибок, берем общее сообщение
|
||||
final message = e.response?.data['message'] as String?;
|
||||
errorMessage = message ?? 'Ошибка при регистрации';
|
||||
emit(state.copyWith(registrationError: errorMessage));
|
||||
}
|
||||
} catch (e) {
|
||||
log(e.toString());
|
||||
errorMessage = e.toString();
|
||||
emit(state.copyWith(registrationError: errorMessage));
|
||||
}
|
||||
return (false, didApiComplainOnValidation);
|
||||
}
|
||||
|
||||
Future<String> _generatePassword() async {
|
||||
final generator = GPassword();
|
||||
final password = generator.generate(passwordLength: 10);
|
||||
emit(state.copyWith(password: password));
|
||||
return password;
|
||||
}
|
||||
}
|
||||
import 'dart:developer';
|
||||
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:eatvio_app/core/token_storage.dart';
|
||||
import 'package:eatvio_app/core/utils/date_time_utils.dart';
|
||||
import 'package:eatvio_app/core/utils/validation_utils.dart';
|
||||
import 'package:eatvio_app/features/registration_v2/cubit/registration_state.dart';
|
||||
import 'package:eatvio_app/features/registration_v2/models/registration_model.dart';
|
||||
import 'package:eatvio_app/features/registration_v2/repositories/registration_repository_v2.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:eatvio_app/core/error_reporting/report_from.dart';
|
||||
import 'package:gpassword/gpassword.dart';
|
||||
|
||||
class RegistrationCubitV2 extends Cubit<RegistrationStateV2> {
|
||||
final RegistrationRepositoryV2 registrationRepository;
|
||||
RegistrationCubitV2({required this.registrationRepository}) : super(const RegistrationStateV2());
|
||||
|
||||
void setFirstName(String firstName) {
|
||||
emit(state.copyWith(firstName: firstName));
|
||||
validateFirstName();
|
||||
}
|
||||
|
||||
void setLastName(String lastName) {
|
||||
emit(state.copyWith(lastName: lastName));
|
||||
validateLastName();
|
||||
}
|
||||
|
||||
void setEmail(String email) {
|
||||
emit(state.copyWith(email: email));
|
||||
validateEmail();
|
||||
}
|
||||
|
||||
void setPhone(String phone) {
|
||||
emit(state.copyWith(phone: phone));
|
||||
validatePhone();
|
||||
}
|
||||
|
||||
void setBirthday(DateTime birthday) {
|
||||
emit(state.copyWith(birthday: birthday));
|
||||
validateBirthday();
|
||||
}
|
||||
|
||||
void setGender(String gender) {
|
||||
emit(state.copyWith(gender: gender));
|
||||
validateGender();
|
||||
}
|
||||
|
||||
void setWeight(int weight) {
|
||||
emit(state.copyWith(weight: weight));
|
||||
validateWeight();
|
||||
}
|
||||
|
||||
void setHeight(int height) {
|
||||
emit(state.copyWith(height: height));
|
||||
validateHeight();
|
||||
}
|
||||
|
||||
void setActivityCoefficient(double activityCoefficient) {
|
||||
emit(state.copyWith(activityCoefficient: activityCoefficient));
|
||||
validateActivityCoefficient();
|
||||
}
|
||||
|
||||
void setPassword(String password) {
|
||||
emit(state.copyWith(password: password));
|
||||
}
|
||||
|
||||
bool validateFirstName() {
|
||||
if (state.firstName.isEmpty) {
|
||||
emit(state.copyWith(isFirstNameValid: false));
|
||||
return false;
|
||||
}
|
||||
emit(state.copyWith(isFirstNameValid: true));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool validateLastName() {
|
||||
if (state.lastName.isEmpty) {
|
||||
emit(state.copyWith(isLastNameValid: false));
|
||||
return false;
|
||||
}
|
||||
emit(state.copyWith(isLastNameValid: true));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool validateEmail() {
|
||||
if (state.email.isEmpty) {
|
||||
emit(state.copyWith(isEmailValid: false));
|
||||
return false;
|
||||
}
|
||||
emit(state.copyWith(isEmailValid: true));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool validatePhone() {
|
||||
if (state.phone.isEmpty) {
|
||||
emit(state.copyWith(isPhoneValid: false));
|
||||
return false;
|
||||
}
|
||||
emit(state.copyWith(isPhoneValid: true));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool validateGender() {
|
||||
if (state.gender.isEmpty) {
|
||||
emit(state.copyWith(isGenderValid: false));
|
||||
return false;
|
||||
}
|
||||
emit(state.copyWith(isGenderValid: true));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool validateWeight() {
|
||||
if (state.weight == 0) {
|
||||
emit(state.copyWith(isWeightValid: false));
|
||||
return false;
|
||||
}
|
||||
emit(state.copyWith(isWeightValid: true));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool validateHeight() {
|
||||
if (state.height == 0) {
|
||||
emit(state.copyWith(isHeightValid: false));
|
||||
return false;
|
||||
}
|
||||
emit(state.copyWith(isHeightValid: true));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool validateActivityCoefficient() {
|
||||
if (state.activityCoefficient == 0) {
|
||||
emit(state.copyWith(isActivityCoefficientValid: false));
|
||||
return false;
|
||||
}
|
||||
emit(state.copyWith(isActivityCoefficientValid: true));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool validateBirthday() {
|
||||
if (state.birthday == null) {
|
||||
emit(state.copyWith(isBirthdayValid: false));
|
||||
return false;
|
||||
}
|
||||
emit(state.copyWith(isBirthdayValid: true));
|
||||
return true;
|
||||
}
|
||||
|
||||
void nextStep() {
|
||||
emit(state.copyWith(step: 1));
|
||||
}
|
||||
|
||||
void prevStep() {
|
||||
emit(state.copyWith(step: 0));
|
||||
}
|
||||
|
||||
bool validateAllFields() {
|
||||
if (!validateFirstName() ||
|
||||
!validateLastName() ||
|
||||
!validateEmail() ||
|
||||
!validatePhone() ||
|
||||
!validateGender() ||
|
||||
!validateWeight() ||
|
||||
!validateHeight() ||
|
||||
!validateActivityCoefficient() ||
|
||||
!validateBirthday()) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
Future<(bool, bool)> register() async {
|
||||
if (!validateAllFields()) {
|
||||
return (false, true);
|
||||
}
|
||||
final birthday = state.birthday?.format('yyyy-MM-dd');
|
||||
if (birthday == null) {
|
||||
validateBirthday();
|
||||
return (false, true);
|
||||
}
|
||||
final password = await _generatePassword();
|
||||
final registrationModel = RegistrationModel(
|
||||
firstName: state.firstName,
|
||||
lastName: state.lastName,
|
||||
email: state.email,
|
||||
phone: ValidationUtils.normalizePhone(state.phone),
|
||||
gender: state.gender,
|
||||
password: password,
|
||||
confirmPassword: password,
|
||||
weight: state.weight,
|
||||
height: state.height,
|
||||
activityCoefficient: state.activityCoefficient,
|
||||
birthday: birthday,
|
||||
);
|
||||
bool didApiComplainOnValidation = false;
|
||||
String errorMessage = '';
|
||||
try {
|
||||
final token = await registrationRepository.register(registrationModel: registrationModel);
|
||||
if (token != null) {
|
||||
TokenStorage.saveTokenInStorage(token);
|
||||
emit(state.copyWith(registrationError: null));
|
||||
return (true, false);
|
||||
}
|
||||
} on DioException catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
final errors = e.response?.data['errors'] as Map<String, dynamic>?;
|
||||
final emailErrors = errors?['email'] as List<dynamic>?;
|
||||
final phoneErrors = errors?['phone'] as List<dynamic>?;
|
||||
final dateOfBirth = errors?['date_of_birth'] as List<dynamic>?;
|
||||
|
||||
// Собираем все ошибки для отображения в диалоге
|
||||
List<String> allErrors = [];
|
||||
|
||||
if (emailErrors != null && emailErrors.isNotEmpty) {
|
||||
for (var error in emailErrors) {
|
||||
allErrors.add(error.toString());
|
||||
if (error.toString() == 'Некорректный формат email') {
|
||||
emit(state.copyWith(isEmailValid: false, emailDisplayError: 'Некорректный формат email'));
|
||||
didApiComplainOnValidation = true;
|
||||
}
|
||||
if (error.toString() == 'Такой Эл. почта уже существует.') {
|
||||
emit(state.copyWith(isEmailValid: false, emailDisplayError: 'Такая Эл. почта уже существует.'));
|
||||
didApiComplainOnValidation = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (phoneErrors != null && phoneErrors.isNotEmpty) {
|
||||
for (var error in phoneErrors) {
|
||||
allErrors.add(error.toString());
|
||||
if (error.toString() == 'Такой phone уже существует.') {
|
||||
emit(state.copyWith(isPhoneValid: false, phoneDisplayError: 'Такой номер телефона уже существует.'));
|
||||
didApiComplainOnValidation = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (dateOfBirth != null && dateOfBirth.isNotEmpty) {
|
||||
for (var error in dateOfBirth) {
|
||||
allErrors.add(error.toString());
|
||||
if (error.toString() == 'Некорректный формат даты рождения') {
|
||||
emit(state.copyWith(isBirthdayValid: false, dateOfBirthDisplayError: 'Некорректный формат даты рождения'));
|
||||
didApiComplainOnValidation = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Сохраняем все ошибки для отображения в диалоге
|
||||
if (allErrors.isNotEmpty) {
|
||||
errorMessage = allErrors.join('\n');
|
||||
emit(state.copyWith(registrationError: errorMessage));
|
||||
} else {
|
||||
// Если нет конкретных ошибок, берем общее сообщение
|
||||
final message = e.response?.data['message'] as String?;
|
||||
errorMessage = message ?? 'Ошибка при регистрации';
|
||||
emit(state.copyWith(registrationError: errorMessage));
|
||||
}
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
log(e.toString());
|
||||
errorMessage = e.toString();
|
||||
emit(state.copyWith(registrationError: errorMessage));
|
||||
}
|
||||
return (false, didApiComplainOnValidation);
|
||||
}
|
||||
|
||||
Future<String> _generatePassword() async {
|
||||
final generator = GPassword();
|
||||
final password = generator.generate(passwordLength: 10);
|
||||
emit(state.copyWith(password: password));
|
||||
return password;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,18 +1,13 @@
|
||||
import 'package:eatvio_app/features/registration_v2/models/registration_model.dart';
|
||||
import 'package:eatvio_app/features/registration_v2/services/registration_service_v2.dart';
|
||||
import 'package:sentry_flutter/sentry_flutter.dart';
|
||||
|
||||
class RegistrationRepositoryV2 {
|
||||
final RegistrationServiceV2 registrationService;
|
||||
RegistrationRepositoryV2({required this.registrationService});
|
||||
|
||||
Future<String?> register({required RegistrationModel registrationModel}) async {
|
||||
try {
|
||||
final response = await registrationService.register(model: registrationModel.toJson());
|
||||
return response['token'];
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
}
|
||||
final response = await registrationService.register(model: registrationModel.toJson());
|
||||
return response['token'];
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ import 'package:eatvio_app/features/settings/models/profile_settings_model.dart'
|
||||
import 'package:eatvio_app/features/settings/presentation/bloc/settings_cubit/settings_state.dart';
|
||||
import 'package:eatvio_app/features/settings/repositories/service_repository.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:eatvio_app/core/error_reporting/report_from.dart';
|
||||
|
||||
class SettingsCubit extends Cubit<SettingsState> {
|
||||
final ProfileRepository profileRepository;
|
||||
@@ -36,20 +37,23 @@ class SettingsCubit extends Cubit<SettingsState> {
|
||||
} else {
|
||||
consultantInfo = null;
|
||||
}
|
||||
} catch (e) {
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
consultantInfo = null;
|
||||
}
|
||||
|
||||
try {
|
||||
hasActiveConsultation = await _checkActiveConsultation();
|
||||
} catch (e) {
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
hasActiveConsultation = false;
|
||||
}
|
||||
|
||||
try {
|
||||
final oauthResponse = await settingsRepository.getOAuthAccounts();
|
||||
oauthAccounts = oauthResponse.data;
|
||||
} catch (e) {
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
oauthAccounts = null;
|
||||
}
|
||||
|
||||
@@ -64,7 +68,8 @@ class SettingsCubit extends Cubit<SettingsState> {
|
||||
oauthAccounts: oauthAccounts,
|
||||
),
|
||||
);
|
||||
} catch (e) {
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
emit(SettingsState.error(errorMessage: e.toString()));
|
||||
}
|
||||
}
|
||||
@@ -72,8 +77,8 @@ class SettingsCubit extends Cubit<SettingsState> {
|
||||
Future<void> updateProfileDetails({required ProfileDetailsModel profileDetailsModel}) async {
|
||||
try {
|
||||
await settingsRepository.updateProfileDetails(profileDetailsModel: profileDetailsModel);
|
||||
} catch (e) {
|
||||
rethrow;
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
} finally {
|
||||
await init();
|
||||
}
|
||||
@@ -82,8 +87,8 @@ class SettingsCubit extends Cubit<SettingsState> {
|
||||
Future<void> updateProfileSettings({required ProfileSettingsModel profileSettingsModel}) async {
|
||||
try {
|
||||
await settingsRepository.updateProfileSettings(profileSettingsModel: profileSettingsModel);
|
||||
} catch (e) {
|
||||
rethrow;
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
} finally {
|
||||
await init();
|
||||
}
|
||||
@@ -93,7 +98,8 @@ class SettingsCubit extends Cubit<SettingsState> {
|
||||
try {
|
||||
await profileRepository.deleteAccount();
|
||||
return true;
|
||||
} catch (e) {
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -113,8 +119,8 @@ class SettingsCubit extends Cubit<SettingsState> {
|
||||
);
|
||||
await settingsRepository.linkOAuthAccount(request: request);
|
||||
await init();
|
||||
} catch (e) {
|
||||
rethrow;
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -122,8 +128,8 @@ class SettingsCubit extends Cubit<SettingsState> {
|
||||
try {
|
||||
await settingsRepository.unlinkOAuthAccount(provider: provider);
|
||||
await init();
|
||||
} catch (e) {
|
||||
rethrow;
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -135,7 +141,8 @@ class SettingsCubit extends Cubit<SettingsState> {
|
||||
return userPurchases.any((purchase) =>
|
||||
activeStates.contains(purchase.chosenPlanState)
|
||||
);
|
||||
} catch (e) {
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,6 @@ import 'package:eatvio_app/features/settings/models/oauth_account_model.dart';
|
||||
import 'package:eatvio_app/features/settings/models/oauth_attach_request.dart';
|
||||
import 'package:eatvio_app/features/settings/models/profile_settings_model.dart';
|
||||
import 'package:eatvio_app/features/settings/services/settings_service.dart';
|
||||
import 'package:sentry_flutter/sentry_flutter.dart';
|
||||
|
||||
class SettingsRepository {
|
||||
final SettingsService settingsService;
|
||||
@@ -11,56 +10,32 @@ class SettingsRepository {
|
||||
const SettingsRepository({required this.settingsService});
|
||||
|
||||
Future<ProfileSettingsModel> getProfileSettings() async {
|
||||
try {
|
||||
return await settingsService.getProfileSettings();
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
}
|
||||
return await settingsService.getProfileSettings();
|
||||
|
||||
}
|
||||
|
||||
Future<ProfileSettingsModel> updateProfileSettings({required ProfileSettingsModel profileSettingsModel}) async {
|
||||
try {
|
||||
return await settingsService.updateProfileSettings(data: profileSettingsModel.toJson());
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
}
|
||||
return await settingsService.updateProfileSettings(data: profileSettingsModel.toJson());
|
||||
|
||||
}
|
||||
|
||||
Future<ProfileDetailsModel> updateProfileDetails({required ProfileDetailsModel profileDetailsModel}) async {
|
||||
try {
|
||||
return await settingsService.updateProfileDetails(data: profileDetailsModel.toJson());
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
}
|
||||
return await settingsService.updateProfileDetails(data: profileDetailsModel.toJson());
|
||||
|
||||
}
|
||||
|
||||
Future<OAuthAccountsResponseModel> getOAuthAccounts() async {
|
||||
try {
|
||||
return await settingsService.getOAuthAccounts();
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
}
|
||||
return await settingsService.getOAuthAccounts();
|
||||
|
||||
}
|
||||
|
||||
Future<void> linkOAuthAccount({required OAuthAttachRequest request}) async {
|
||||
try {
|
||||
return await settingsService.linkOAuthAccount(request);
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
}
|
||||
return await settingsService.linkOAuthAccount(request);
|
||||
|
||||
}
|
||||
|
||||
Future<void> unlinkOAuthAccount({required String provider}) async {
|
||||
try {
|
||||
return await settingsService.unlinkOAuthAccount(provider);
|
||||
} catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
rethrow;
|
||||
}
|
||||
return await settingsService.unlinkOAuthAccount(provider);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ import 'dart:developer';
|
||||
import 'package:eatvio_app/features/profile/repositories/profile_repository.dart';
|
||||
import 'package:eatvio_app/features/user_details/presentation/cubit/user_details_state.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:eatvio_app/core/error_reporting/report_from.dart';
|
||||
|
||||
class UserDetailsCubit extends Cubit<UserDetailsState> {
|
||||
final ProfileRepository profileRepository;
|
||||
@@ -14,7 +15,8 @@ class UserDetailsCubit extends Cubit<UserDetailsState> {
|
||||
final profileDetails = await profileRepository.getProfileDetailsBySlug(slug);
|
||||
emit(state.copyWith(profileDetails: profileDetails, isLoading: false));
|
||||
getChartData(slug: slug);
|
||||
} catch (e) {
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
log(e.toString());
|
||||
emit(state.copyWith(error: e.toString(), isLoading: false));
|
||||
}
|
||||
@@ -26,6 +28,7 @@ class UserDetailsCubit extends Cubit<UserDetailsState> {
|
||||
final circumferencePoints = await profileRepository.getCircumferences(period: period, slug: slug);
|
||||
emit(state.copyWith(weightPoints: weightPoints, circumferencePoints: circumferencePoints));
|
||||
} catch (e, stackTrace) {
|
||||
await reportFrom(e, stackTrace, this);
|
||||
log(e.toString(), stackTrace: stackTrace);
|
||||
emit(state.copyWith(error: e.toString(), isLoading: false));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user