forked from eatvio/eatvio_app
Merge pull request 'main' (#14) from eatvio/eatvio_app:main into main
Reviewed-on: BLoC/eatvio_app#14
This commit is contained in:
@@ -3,7 +3,7 @@ name: Eatvio App Android Test
|
||||
on: [ pull_request ]
|
||||
|
||||
env:
|
||||
flutter_version: "3.27.0"
|
||||
flutter_version: "3.27.3"
|
||||
java_version: "21.x"
|
||||
flutter_channel: "stable"
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ name: Eatvio App Android Test on custom docker
|
||||
on: [ pull_request ]
|
||||
|
||||
env:
|
||||
flutter_version: "3.27.0"
|
||||
flutter_version: "3.27.3"
|
||||
java_version: "21.x"
|
||||
flutter_channel: "stable"
|
||||
my_local_cache_dir: "/opt/hostedtoolcache/"
|
||||
|
||||
@@ -3,7 +3,7 @@ name: Eatvio App Android Test
|
||||
on: [ pull_request ]
|
||||
|
||||
env:
|
||||
flutter_version: "3.27.0"
|
||||
flutter_version: "3.27.3"
|
||||
java_version: "21.x"
|
||||
flutter_channel: "stable"
|
||||
my_local_cache_dir: "/opt/hostedtoolcache/"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import 'package:eatvio_app/core/initialization_cubit/initialization_cubit.dart';
|
||||
import 'package:eatvio_app/core/initialization_cubit/ws_manager.dart';
|
||||
import 'package:eatvio_app/core/locator_service.dart';
|
||||
import 'package:eatvio_app/core/token_storage.dart';
|
||||
import 'package:eatvio_app/features/auth/auth_screen/auth_screen.dart';
|
||||
@@ -15,6 +15,7 @@ import 'package:eatvio_app/features/consultant/become_consultant/presentation/pa
|
||||
import 'package:eatvio_app/features/create_diet/presentation/create_diet_screen.dart';
|
||||
import 'package:eatvio_app/features/create_diet/presentation/diet_preview_screen.dart';
|
||||
import 'package:eatvio_app/features/create_plan/presentation/create_plan_screen.dart';
|
||||
import 'package:eatvio_app/features/dev_tools/presentation/dev_tools_screen.dart';
|
||||
import 'package:eatvio_app/features/diary/presentation/pages/diary_screen.dart';
|
||||
import 'package:eatvio_app/features/diets/presentation/pages/about_diet_screen.dart';
|
||||
import 'package:eatvio_app/features/feed/models/diets_pagination_model.dart';
|
||||
@@ -80,7 +81,7 @@ class AppRouter {
|
||||
path: '/my-profile-screen',
|
||||
name: 'myProfileScreen',
|
||||
redirect: (context, state) async {
|
||||
await sl<InitializationCubit>().runInitialization();
|
||||
await sl<WsManager>().initialize();
|
||||
return null;
|
||||
},
|
||||
pageBuilder: (context, state) => NoTransitionPage(child: ProfileScreen()),
|
||||
@@ -308,6 +309,11 @@ class AppRouter {
|
||||
slug: state.extra as String,
|
||||
),
|
||||
),
|
||||
GoRoute(
|
||||
path: DevToolsScreen.path,
|
||||
name: DevToolsScreen.name,
|
||||
builder: (context, state) => DevToolsScreen(),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,7 +1,11 @@
|
||||
String baseUrl = 'https://eatvio.ru';
|
||||
// String baseUrl = 'https://dev2.eatvio.com';
|
||||
// String baseUrl = 'https://eatvio.ru';
|
||||
String baseUrl = 'https://dev2.eatvio.com';
|
||||
|
||||
const List<int> durationValues = [7, 14, 21];
|
||||
|
||||
const List<String> dietTypeValues = ['veg', 'light', 'carb', 'meat'];
|
||||
const List<String> planTypeValues = ['fit', 'slim', 'wellness', 'behavior'];
|
||||
|
||||
const newMessagesChannelName = 'private-new-chat-messages';
|
||||
const newNotificationsChannelName = 'private-message-events';
|
||||
const directChatChannelName = 'private-direct-chat';
|
||||
|
||||
@@ -1,105 +0,0 @@
|
||||
import 'package:dart_pusher_channels/dart_pusher_channels.dart';
|
||||
import 'package:eatvio_app/core/const.dart';
|
||||
import 'package:eatvio_app/core/initialization_cubit/initialization_state.dart';
|
||||
import 'package:eatvio_app/core/token_storage.dart';
|
||||
import 'package:eatvio_app/features/bottom_navigation_bar/presentation/bloc/new_messages_cubit/new_messages_cubit.dart';
|
||||
import 'package:eatvio_app/features/bottom_navigation_bar/presentation/bloc/notifications_cubit/notifications_cubit.dart';
|
||||
import 'package:eatvio_app/features/chat/repositories/chat_repository.dart';
|
||||
import 'package:eatvio_app/core/locator_service.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
|
||||
class InitializationCubit extends Cubit<InitializationState> {
|
||||
final ChatRepository chatRepository;
|
||||
bool wasInitialized = false;
|
||||
|
||||
InitializationCubit({required this.chatRepository}) : super(const InitializationState.loading());
|
||||
|
||||
Future<void> subscribeNotifications(int userId, PusherChannelsClient client) async {
|
||||
final privateNotificationChannel = await client.privateChannel(
|
||||
'private-message-events.$userId',
|
||||
authorizationDelegate: EndpointAuthorizableChannelTokenAuthorizationDelegate.forPrivateChannel(
|
||||
authorizationEndpoint: Uri.parse(baseUrl + '/broadcasting/auth'),
|
||||
headers: {
|
||||
'Authorization': 'Bearer ${await TokenStorage.getTokenFromStorage()}',
|
||||
},
|
||||
),
|
||||
);
|
||||
|
||||
privateNotificationChannel.subscribe();
|
||||
|
||||
privateNotificationChannel.bindToAll().listen((event) {
|
||||
sl<NotificationsCubit>().incrementCounter(event.name);
|
||||
});
|
||||
}
|
||||
|
||||
Future<void> subscribeChatMessages(int userId, PusherChannelsClient client) async {
|
||||
final privateMessagesChannel = await client.privateChannel(
|
||||
'private-new-chat-messages.$userId',
|
||||
authorizationDelegate: EndpointAuthorizableChannelTokenAuthorizationDelegate.forPrivateChannel(
|
||||
authorizationEndpoint: Uri.parse(baseUrl + '/broadcasting/auth'),
|
||||
headers: {
|
||||
'Authorization': 'Bearer ${await TokenStorage.getTokenFromStorage()}',
|
||||
},
|
||||
),
|
||||
);
|
||||
|
||||
privateMessagesChannel.subscribe();
|
||||
|
||||
privateMessagesChannel.bindToAll().listen((event) {
|
||||
sl<NewMessagesCubit>().incrementCounter();
|
||||
});
|
||||
}
|
||||
|
||||
Future<void> runInitialization() async {
|
||||
if (!wasInitialized) {
|
||||
wasInitialized = true;
|
||||
try {
|
||||
await TokenStorage.haveTokenInStorage();
|
||||
final wsUrl = await chatRepository.getWebsocket();
|
||||
final options = PusherChannelsOptions.fromHost(
|
||||
scheme: 'wss',
|
||||
key: wsUrl.key,
|
||||
host: wsUrl.host,
|
||||
shouldSupplyMetadataQueries: true,
|
||||
metadata: PusherChannelsOptionsMetadata.byDefault(),
|
||||
port: 443,
|
||||
);
|
||||
final client = PusherChannelsClient.websocket(
|
||||
options: options,
|
||||
connectionErrorHandler: (exception, trace, refresh) {
|
||||
refresh();
|
||||
},
|
||||
minimumReconnectDelayDuration: const Duration(
|
||||
seconds: 1,
|
||||
),
|
||||
defaultActivityDuration: const Duration(
|
||||
seconds: 120,
|
||||
),
|
||||
activityDurationOverride: const Duration(
|
||||
seconds: 120,
|
||||
),
|
||||
waitForPongDuration: const Duration(
|
||||
seconds: 30,
|
||||
),
|
||||
);
|
||||
await client.connect();
|
||||
|
||||
await subscribeNotifications(wsUrl.userId, client);
|
||||
await subscribeChatMessages(wsUrl.userId, client);
|
||||
|
||||
emit(
|
||||
InitializationState.success(
|
||||
client: client,
|
||||
),
|
||||
);
|
||||
} catch (e) {
|
||||
emit(
|
||||
InitializationState.error(
|
||||
errorMessage: e.toString(),
|
||||
),
|
||||
);
|
||||
rethrow;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
import 'package:dart_pusher_channels/dart_pusher_channels.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
|
||||
part 'initialization_state.freezed.dart';
|
||||
|
||||
@freezed
|
||||
abstract class InitializationState with _$InitializationState {
|
||||
const factory InitializationState() = _InitializationState;
|
||||
|
||||
const factory InitializationState.loading() = InitializationStateLoading;
|
||||
|
||||
const factory InitializationState.success({
|
||||
required PusherChannelsClient client,
|
||||
}) = InitializationStateSuccess;
|
||||
|
||||
const factory InitializationState.error({
|
||||
required String errorMessage,
|
||||
}) = InitializationStateError;
|
||||
}
|
||||
@@ -1,645 +0,0 @@
|
||||
// coverage:ignore-file
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
// ignore_for_file: type=lint
|
||||
// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark
|
||||
|
||||
part of 'initialization_state.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// FreezedGenerator
|
||||
// **************************************************************************
|
||||
|
||||
T _$identity<T>(T value) => value;
|
||||
|
||||
final _privateConstructorUsedError = UnsupportedError(
|
||||
'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#adding-getters-and-methods-to-our-models');
|
||||
|
||||
/// @nodoc
|
||||
mixin _$InitializationState {
|
||||
@optionalTypeArgs
|
||||
TResult when<TResult extends Object?>(
|
||||
TResult Function() $default, {
|
||||
required TResult Function() loading,
|
||||
required TResult Function(PusherChannelsClient client) success,
|
||||
required TResult Function(String errorMessage) error,
|
||||
}) =>
|
||||
throw _privateConstructorUsedError;
|
||||
@optionalTypeArgs
|
||||
TResult? whenOrNull<TResult extends Object?>(
|
||||
TResult? Function()? $default, {
|
||||
TResult? Function()? loading,
|
||||
TResult? Function(PusherChannelsClient client)? success,
|
||||
TResult? Function(String errorMessage)? error,
|
||||
}) =>
|
||||
throw _privateConstructorUsedError;
|
||||
@optionalTypeArgs
|
||||
TResult maybeWhen<TResult extends Object?>(
|
||||
TResult Function()? $default, {
|
||||
TResult Function()? loading,
|
||||
TResult Function(PusherChannelsClient client)? success,
|
||||
TResult Function(String errorMessage)? error,
|
||||
required TResult orElse(),
|
||||
}) =>
|
||||
throw _privateConstructorUsedError;
|
||||
@optionalTypeArgs
|
||||
TResult map<TResult extends Object?>(
|
||||
TResult Function(_InitializationState value) $default, {
|
||||
required TResult Function(InitializationStateLoading value) loading,
|
||||
required TResult Function(InitializationStateSuccess value) success,
|
||||
required TResult Function(InitializationStateError value) error,
|
||||
}) =>
|
||||
throw _privateConstructorUsedError;
|
||||
@optionalTypeArgs
|
||||
TResult? mapOrNull<TResult extends Object?>(
|
||||
TResult? Function(_InitializationState value)? $default, {
|
||||
TResult? Function(InitializationStateLoading value)? loading,
|
||||
TResult? Function(InitializationStateSuccess value)? success,
|
||||
TResult? Function(InitializationStateError value)? error,
|
||||
}) =>
|
||||
throw _privateConstructorUsedError;
|
||||
@optionalTypeArgs
|
||||
TResult maybeMap<TResult extends Object?>(
|
||||
TResult Function(_InitializationState value)? $default, {
|
||||
TResult Function(InitializationStateLoading value)? loading,
|
||||
TResult Function(InitializationStateSuccess value)? success,
|
||||
TResult Function(InitializationStateError value)? error,
|
||||
required TResult orElse(),
|
||||
}) =>
|
||||
throw _privateConstructorUsedError;
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract class $InitializationStateCopyWith<$Res> {
|
||||
factory $InitializationStateCopyWith(
|
||||
InitializationState value, $Res Function(InitializationState) then) =
|
||||
_$InitializationStateCopyWithImpl<$Res, InitializationState>;
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
class _$InitializationStateCopyWithImpl<$Res, $Val extends InitializationState>
|
||||
implements $InitializationStateCopyWith<$Res> {
|
||||
_$InitializationStateCopyWithImpl(this._value, this._then);
|
||||
|
||||
// ignore: unused_field
|
||||
final $Val _value;
|
||||
// ignore: unused_field
|
||||
final $Res Function($Val) _then;
|
||||
|
||||
/// Create a copy of InitializationState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract class _$$InitializationStateImplCopyWith<$Res> {
|
||||
factory _$$InitializationStateImplCopyWith(_$InitializationStateImpl value,
|
||||
$Res Function(_$InitializationStateImpl) then) =
|
||||
__$$InitializationStateImplCopyWithImpl<$Res>;
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
class __$$InitializationStateImplCopyWithImpl<$Res>
|
||||
extends _$InitializationStateCopyWithImpl<$Res, _$InitializationStateImpl>
|
||||
implements _$$InitializationStateImplCopyWith<$Res> {
|
||||
__$$InitializationStateImplCopyWithImpl(_$InitializationStateImpl _value,
|
||||
$Res Function(_$InitializationStateImpl) _then)
|
||||
: super(_value, _then);
|
||||
|
||||
/// Create a copy of InitializationState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
|
||||
class _$InitializationStateImpl implements _InitializationState {
|
||||
const _$InitializationStateImpl();
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'InitializationState()';
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) ||
|
||||
(other.runtimeType == runtimeType &&
|
||||
other is _$InitializationStateImpl);
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode => runtimeType.hashCode;
|
||||
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult when<TResult extends Object?>(
|
||||
TResult Function() $default, {
|
||||
required TResult Function() loading,
|
||||
required TResult Function(PusherChannelsClient client) success,
|
||||
required TResult Function(String errorMessage) error,
|
||||
}) {
|
||||
return $default();
|
||||
}
|
||||
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult? whenOrNull<TResult extends Object?>(
|
||||
TResult? Function()? $default, {
|
||||
TResult? Function()? loading,
|
||||
TResult? Function(PusherChannelsClient client)? success,
|
||||
TResult? Function(String errorMessage)? error,
|
||||
}) {
|
||||
return $default?.call();
|
||||
}
|
||||
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult maybeWhen<TResult extends Object?>(
|
||||
TResult Function()? $default, {
|
||||
TResult Function()? loading,
|
||||
TResult Function(PusherChannelsClient client)? success,
|
||||
TResult Function(String errorMessage)? error,
|
||||
required TResult orElse(),
|
||||
}) {
|
||||
if ($default != null) {
|
||||
return $default();
|
||||
}
|
||||
return orElse();
|
||||
}
|
||||
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult map<TResult extends Object?>(
|
||||
TResult Function(_InitializationState value) $default, {
|
||||
required TResult Function(InitializationStateLoading value) loading,
|
||||
required TResult Function(InitializationStateSuccess value) success,
|
||||
required TResult Function(InitializationStateError value) error,
|
||||
}) {
|
||||
return $default(this);
|
||||
}
|
||||
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult? mapOrNull<TResult extends Object?>(
|
||||
TResult? Function(_InitializationState value)? $default, {
|
||||
TResult? Function(InitializationStateLoading value)? loading,
|
||||
TResult? Function(InitializationStateSuccess value)? success,
|
||||
TResult? Function(InitializationStateError value)? error,
|
||||
}) {
|
||||
return $default?.call(this);
|
||||
}
|
||||
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult maybeMap<TResult extends Object?>(
|
||||
TResult Function(_InitializationState value)? $default, {
|
||||
TResult Function(InitializationStateLoading value)? loading,
|
||||
TResult Function(InitializationStateSuccess value)? success,
|
||||
TResult Function(InitializationStateError value)? error,
|
||||
required TResult orElse(),
|
||||
}) {
|
||||
if ($default != null) {
|
||||
return $default(this);
|
||||
}
|
||||
return orElse();
|
||||
}
|
||||
}
|
||||
|
||||
abstract class _InitializationState implements InitializationState {
|
||||
const factory _InitializationState() = _$InitializationStateImpl;
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract class _$$InitializationStateLoadingImplCopyWith<$Res> {
|
||||
factory _$$InitializationStateLoadingImplCopyWith(
|
||||
_$InitializationStateLoadingImpl value,
|
||||
$Res Function(_$InitializationStateLoadingImpl) then) =
|
||||
__$$InitializationStateLoadingImplCopyWithImpl<$Res>;
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
class __$$InitializationStateLoadingImplCopyWithImpl<$Res>
|
||||
extends _$InitializationStateCopyWithImpl<$Res,
|
||||
_$InitializationStateLoadingImpl>
|
||||
implements _$$InitializationStateLoadingImplCopyWith<$Res> {
|
||||
__$$InitializationStateLoadingImplCopyWithImpl(
|
||||
_$InitializationStateLoadingImpl _value,
|
||||
$Res Function(_$InitializationStateLoadingImpl) _then)
|
||||
: super(_value, _then);
|
||||
|
||||
/// Create a copy of InitializationState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
|
||||
class _$InitializationStateLoadingImpl implements InitializationStateLoading {
|
||||
const _$InitializationStateLoadingImpl();
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'InitializationState.loading()';
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) ||
|
||||
(other.runtimeType == runtimeType &&
|
||||
other is _$InitializationStateLoadingImpl);
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode => runtimeType.hashCode;
|
||||
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult when<TResult extends Object?>(
|
||||
TResult Function() $default, {
|
||||
required TResult Function() loading,
|
||||
required TResult Function(PusherChannelsClient client) success,
|
||||
required TResult Function(String errorMessage) error,
|
||||
}) {
|
||||
return loading();
|
||||
}
|
||||
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult? whenOrNull<TResult extends Object?>(
|
||||
TResult? Function()? $default, {
|
||||
TResult? Function()? loading,
|
||||
TResult? Function(PusherChannelsClient client)? success,
|
||||
TResult? Function(String errorMessage)? error,
|
||||
}) {
|
||||
return loading?.call();
|
||||
}
|
||||
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult maybeWhen<TResult extends Object?>(
|
||||
TResult Function()? $default, {
|
||||
TResult Function()? loading,
|
||||
TResult Function(PusherChannelsClient client)? success,
|
||||
TResult Function(String errorMessage)? error,
|
||||
required TResult orElse(),
|
||||
}) {
|
||||
if (loading != null) {
|
||||
return loading();
|
||||
}
|
||||
return orElse();
|
||||
}
|
||||
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult map<TResult extends Object?>(
|
||||
TResult Function(_InitializationState value) $default, {
|
||||
required TResult Function(InitializationStateLoading value) loading,
|
||||
required TResult Function(InitializationStateSuccess value) success,
|
||||
required TResult Function(InitializationStateError value) error,
|
||||
}) {
|
||||
return loading(this);
|
||||
}
|
||||
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult? mapOrNull<TResult extends Object?>(
|
||||
TResult? Function(_InitializationState value)? $default, {
|
||||
TResult? Function(InitializationStateLoading value)? loading,
|
||||
TResult? Function(InitializationStateSuccess value)? success,
|
||||
TResult? Function(InitializationStateError value)? error,
|
||||
}) {
|
||||
return loading?.call(this);
|
||||
}
|
||||
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult maybeMap<TResult extends Object?>(
|
||||
TResult Function(_InitializationState value)? $default, {
|
||||
TResult Function(InitializationStateLoading value)? loading,
|
||||
TResult Function(InitializationStateSuccess value)? success,
|
||||
TResult Function(InitializationStateError value)? error,
|
||||
required TResult orElse(),
|
||||
}) {
|
||||
if (loading != null) {
|
||||
return loading(this);
|
||||
}
|
||||
return orElse();
|
||||
}
|
||||
}
|
||||
|
||||
abstract class InitializationStateLoading implements InitializationState {
|
||||
const factory InitializationStateLoading() = _$InitializationStateLoadingImpl;
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract class _$$InitializationStateSuccessImplCopyWith<$Res> {
|
||||
factory _$$InitializationStateSuccessImplCopyWith(
|
||||
_$InitializationStateSuccessImpl value,
|
||||
$Res Function(_$InitializationStateSuccessImpl) then) =
|
||||
__$$InitializationStateSuccessImplCopyWithImpl<$Res>;
|
||||
@useResult
|
||||
$Res call({PusherChannelsClient client});
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
class __$$InitializationStateSuccessImplCopyWithImpl<$Res>
|
||||
extends _$InitializationStateCopyWithImpl<$Res,
|
||||
_$InitializationStateSuccessImpl>
|
||||
implements _$$InitializationStateSuccessImplCopyWith<$Res> {
|
||||
__$$InitializationStateSuccessImplCopyWithImpl(
|
||||
_$InitializationStateSuccessImpl _value,
|
||||
$Res Function(_$InitializationStateSuccessImpl) _then)
|
||||
: super(_value, _then);
|
||||
|
||||
/// Create a copy of InitializationState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@pragma('vm:prefer-inline')
|
||||
@override
|
||||
$Res call({
|
||||
Object? client = null,
|
||||
}) {
|
||||
return _then(_$InitializationStateSuccessImpl(
|
||||
client: null == client
|
||||
? _value.client
|
||||
: client // ignore: cast_nullable_to_non_nullable
|
||||
as PusherChannelsClient,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
|
||||
class _$InitializationStateSuccessImpl implements InitializationStateSuccess {
|
||||
const _$InitializationStateSuccessImpl({required this.client});
|
||||
|
||||
@override
|
||||
final PusherChannelsClient client;
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'InitializationState.success(client: $client)';
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) ||
|
||||
(other.runtimeType == runtimeType &&
|
||||
other is _$InitializationStateSuccessImpl &&
|
||||
(identical(other.client, client) || other.client == client));
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType, client);
|
||||
|
||||
/// Create a copy of InitializationState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@override
|
||||
@pragma('vm:prefer-inline')
|
||||
_$$InitializationStateSuccessImplCopyWith<_$InitializationStateSuccessImpl>
|
||||
get copyWith => __$$InitializationStateSuccessImplCopyWithImpl<
|
||||
_$InitializationStateSuccessImpl>(this, _$identity);
|
||||
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult when<TResult extends Object?>(
|
||||
TResult Function() $default, {
|
||||
required TResult Function() loading,
|
||||
required TResult Function(PusherChannelsClient client) success,
|
||||
required TResult Function(String errorMessage) error,
|
||||
}) {
|
||||
return success(client);
|
||||
}
|
||||
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult? whenOrNull<TResult extends Object?>(
|
||||
TResult? Function()? $default, {
|
||||
TResult? Function()? loading,
|
||||
TResult? Function(PusherChannelsClient client)? success,
|
||||
TResult? Function(String errorMessage)? error,
|
||||
}) {
|
||||
return success?.call(client);
|
||||
}
|
||||
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult maybeWhen<TResult extends Object?>(
|
||||
TResult Function()? $default, {
|
||||
TResult Function()? loading,
|
||||
TResult Function(PusherChannelsClient client)? success,
|
||||
TResult Function(String errorMessage)? error,
|
||||
required TResult orElse(),
|
||||
}) {
|
||||
if (success != null) {
|
||||
return success(client);
|
||||
}
|
||||
return orElse();
|
||||
}
|
||||
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult map<TResult extends Object?>(
|
||||
TResult Function(_InitializationState value) $default, {
|
||||
required TResult Function(InitializationStateLoading value) loading,
|
||||
required TResult Function(InitializationStateSuccess value) success,
|
||||
required TResult Function(InitializationStateError value) error,
|
||||
}) {
|
||||
return success(this);
|
||||
}
|
||||
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult? mapOrNull<TResult extends Object?>(
|
||||
TResult? Function(_InitializationState value)? $default, {
|
||||
TResult? Function(InitializationStateLoading value)? loading,
|
||||
TResult? Function(InitializationStateSuccess value)? success,
|
||||
TResult? Function(InitializationStateError value)? error,
|
||||
}) {
|
||||
return success?.call(this);
|
||||
}
|
||||
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult maybeMap<TResult extends Object?>(
|
||||
TResult Function(_InitializationState value)? $default, {
|
||||
TResult Function(InitializationStateLoading value)? loading,
|
||||
TResult Function(InitializationStateSuccess value)? success,
|
||||
TResult Function(InitializationStateError value)? error,
|
||||
required TResult orElse(),
|
||||
}) {
|
||||
if (success != null) {
|
||||
return success(this);
|
||||
}
|
||||
return orElse();
|
||||
}
|
||||
}
|
||||
|
||||
abstract class InitializationStateSuccess implements InitializationState {
|
||||
const factory InitializationStateSuccess(
|
||||
{required final PusherChannelsClient client}) =
|
||||
_$InitializationStateSuccessImpl;
|
||||
|
||||
PusherChannelsClient get client;
|
||||
|
||||
/// Create a copy of InitializationState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
_$$InitializationStateSuccessImplCopyWith<_$InitializationStateSuccessImpl>
|
||||
get copyWith => throw _privateConstructorUsedError;
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract class _$$InitializationStateErrorImplCopyWith<$Res> {
|
||||
factory _$$InitializationStateErrorImplCopyWith(
|
||||
_$InitializationStateErrorImpl value,
|
||||
$Res Function(_$InitializationStateErrorImpl) then) =
|
||||
__$$InitializationStateErrorImplCopyWithImpl<$Res>;
|
||||
@useResult
|
||||
$Res call({String errorMessage});
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
class __$$InitializationStateErrorImplCopyWithImpl<$Res>
|
||||
extends _$InitializationStateCopyWithImpl<$Res,
|
||||
_$InitializationStateErrorImpl>
|
||||
implements _$$InitializationStateErrorImplCopyWith<$Res> {
|
||||
__$$InitializationStateErrorImplCopyWithImpl(
|
||||
_$InitializationStateErrorImpl _value,
|
||||
$Res Function(_$InitializationStateErrorImpl) _then)
|
||||
: super(_value, _then);
|
||||
|
||||
/// Create a copy of InitializationState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@pragma('vm:prefer-inline')
|
||||
@override
|
||||
$Res call({
|
||||
Object? errorMessage = null,
|
||||
}) {
|
||||
return _then(_$InitializationStateErrorImpl(
|
||||
errorMessage: null == errorMessage
|
||||
? _value.errorMessage
|
||||
: errorMessage // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
|
||||
class _$InitializationStateErrorImpl implements InitializationStateError {
|
||||
const _$InitializationStateErrorImpl({required this.errorMessage});
|
||||
|
||||
@override
|
||||
final String errorMessage;
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'InitializationState.error(errorMessage: $errorMessage)';
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) ||
|
||||
(other.runtimeType == runtimeType &&
|
||||
other is _$InitializationStateErrorImpl &&
|
||||
(identical(other.errorMessage, errorMessage) ||
|
||||
other.errorMessage == errorMessage));
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType, errorMessage);
|
||||
|
||||
/// Create a copy of InitializationState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@override
|
||||
@pragma('vm:prefer-inline')
|
||||
_$$InitializationStateErrorImplCopyWith<_$InitializationStateErrorImpl>
|
||||
get copyWith => __$$InitializationStateErrorImplCopyWithImpl<
|
||||
_$InitializationStateErrorImpl>(this, _$identity);
|
||||
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult when<TResult extends Object?>(
|
||||
TResult Function() $default, {
|
||||
required TResult Function() loading,
|
||||
required TResult Function(PusherChannelsClient client) success,
|
||||
required TResult Function(String errorMessage) error,
|
||||
}) {
|
||||
return error(errorMessage);
|
||||
}
|
||||
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult? whenOrNull<TResult extends Object?>(
|
||||
TResult? Function()? $default, {
|
||||
TResult? Function()? loading,
|
||||
TResult? Function(PusherChannelsClient client)? success,
|
||||
TResult? Function(String errorMessage)? error,
|
||||
}) {
|
||||
return error?.call(errorMessage);
|
||||
}
|
||||
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult maybeWhen<TResult extends Object?>(
|
||||
TResult Function()? $default, {
|
||||
TResult Function()? loading,
|
||||
TResult Function(PusherChannelsClient client)? success,
|
||||
TResult Function(String errorMessage)? error,
|
||||
required TResult orElse(),
|
||||
}) {
|
||||
if (error != null) {
|
||||
return error(errorMessage);
|
||||
}
|
||||
return orElse();
|
||||
}
|
||||
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult map<TResult extends Object?>(
|
||||
TResult Function(_InitializationState value) $default, {
|
||||
required TResult Function(InitializationStateLoading value) loading,
|
||||
required TResult Function(InitializationStateSuccess value) success,
|
||||
required TResult Function(InitializationStateError value) error,
|
||||
}) {
|
||||
return error(this);
|
||||
}
|
||||
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult? mapOrNull<TResult extends Object?>(
|
||||
TResult? Function(_InitializationState value)? $default, {
|
||||
TResult? Function(InitializationStateLoading value)? loading,
|
||||
TResult? Function(InitializationStateSuccess value)? success,
|
||||
TResult? Function(InitializationStateError value)? error,
|
||||
}) {
|
||||
return error?.call(this);
|
||||
}
|
||||
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult maybeMap<TResult extends Object?>(
|
||||
TResult Function(_InitializationState value)? $default, {
|
||||
TResult Function(InitializationStateLoading value)? loading,
|
||||
TResult Function(InitializationStateSuccess value)? success,
|
||||
TResult Function(InitializationStateError value)? error,
|
||||
required TResult orElse(),
|
||||
}) {
|
||||
if (error != null) {
|
||||
return error(this);
|
||||
}
|
||||
return orElse();
|
||||
}
|
||||
}
|
||||
|
||||
abstract class InitializationStateError implements InitializationState {
|
||||
const factory InitializationStateError({required final String errorMessage}) =
|
||||
_$InitializationStateErrorImpl;
|
||||
|
||||
String get errorMessage;
|
||||
|
||||
/// Create a copy of InitializationState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
_$$InitializationStateErrorImplCopyWith<_$InitializationStateErrorImpl>
|
||||
get copyWith => throw _privateConstructorUsedError;
|
||||
}
|
||||
139
lib/core/initialization_cubit/ws_manager.dart
Normal file
139
lib/core/initialization_cubit/ws_manager.dart
Normal file
@@ -0,0 +1,139 @@
|
||||
import 'dart:developer';
|
||||
|
||||
import 'package:dart_pusher_channels/dart_pusher_channels.dart';
|
||||
import 'package:eatvio_app/core/const.dart';
|
||||
import 'package:eatvio_app/core/initialization_cubit/ws_service.dart';
|
||||
import 'package:eatvio_app/core/token_storage.dart';
|
||||
|
||||
class WsManager {
|
||||
final WsService wsService;
|
||||
|
||||
WsManager({required this.wsService});
|
||||
|
||||
PusherChannelsClient? client;
|
||||
int? userId;
|
||||
|
||||
PrivateChannel? _privateNotificationChannel;
|
||||
PrivateChannel? _privateMessagesChannel;
|
||||
PrivateChannel? _privateDirectChatChannel;
|
||||
|
||||
Stream<ChannelReadEvent>? get newMessagesStream => _privateMessagesChannel?.bind('App\\Events\\ChatMessageUpdated');
|
||||
|
||||
// TODO: change name of event to a right one
|
||||
Stream<ChannelReadEvent>? get newNotificationsStream => _privateNotificationChannel?.bind('App\\Events\\ChatMessageUpdated');
|
||||
|
||||
Stream<ChannelReadEvent>? get directChatStream => _privateDirectChatChannel?.bind('App\\Events\\ChatMessageUpdated');
|
||||
|
||||
Stream<ChannelReadEvent>? get clientTypingStream => _privateDirectChatChannel?.bind('client-typing');
|
||||
|
||||
Future<void> initialize() async {
|
||||
if (this.client == null) {
|
||||
try {
|
||||
await TokenStorage.haveTokenInStorage();
|
||||
final wsUrl = await wsService.getWebsocket();
|
||||
|
||||
final options = PusherChannelsOptions.fromHost(
|
||||
scheme: 'wss',
|
||||
key: wsUrl.key,
|
||||
host: wsUrl.host,
|
||||
shouldSupplyMetadataQueries: true,
|
||||
metadata: PusherChannelsOptionsMetadata.byDefault(),
|
||||
port: 443,
|
||||
);
|
||||
client = PusherChannelsClient.websocket(
|
||||
options: options,
|
||||
connectionErrorHandler: (exception, trace, refresh) {
|
||||
refresh();
|
||||
},
|
||||
minimumReconnectDelayDuration: const Duration(
|
||||
seconds: 1,
|
||||
),
|
||||
defaultActivityDuration: const Duration(
|
||||
seconds: 30,
|
||||
),
|
||||
waitForPongDuration: const Duration(
|
||||
seconds: 30,
|
||||
),
|
||||
);
|
||||
|
||||
await client?.connect();
|
||||
|
||||
this.client = client;
|
||||
userId = wsUrl.userId;
|
||||
|
||||
await _initPrivateNotificationsChannel();
|
||||
await _initPrivateMessagesChannel();
|
||||
|
||||
client?.lifecycleStream.listen((data) {
|
||||
if (data == PusherChannelsClientLifeCycleState.establishedConnection) {
|
||||
_unsubscribe();
|
||||
_subscribe();
|
||||
}
|
||||
});
|
||||
client?.eventStream.listen((event) {
|
||||
log(event.rootObject.toString());
|
||||
});
|
||||
_subscribe();
|
||||
} catch (e, st) {
|
||||
log(e.toString(), stackTrace: st);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _initPrivateNotificationsChannel() async {
|
||||
final token = await TokenStorage.getTokenFromStorage();
|
||||
_privateNotificationChannel = await client?.privateChannel(
|
||||
'$newNotificationsChannelName.$userId',
|
||||
authorizationDelegate: EndpointAuthorizableChannelTokenAuthorizationDelegate.forPrivateChannel(
|
||||
authorizationEndpoint: Uri.parse(baseUrl + '/broadcasting/auth'),
|
||||
headers: {
|
||||
'Authorization': 'Bearer $token',
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> _initPrivateMessagesChannel() async {
|
||||
final token = await TokenStorage.getTokenFromStorage();
|
||||
_privateMessagesChannel = await client?.privateChannel(
|
||||
'$newMessagesChannelName.$userId',
|
||||
authorizationDelegate: EndpointAuthorizableChannelTokenAuthorizationDelegate.forPrivateChannel(
|
||||
authorizationEndpoint: Uri.parse(baseUrl + '/broadcasting/auth'),
|
||||
headers: {
|
||||
'Authorization': 'Bearer $token',
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> initPrivateDirectChatChannel(String chatId) async {
|
||||
final token = await TokenStorage.getTokenFromStorage();
|
||||
_privateDirectChatChannel = await client?.privateChannel(
|
||||
'$directChatChannelName.$chatId',
|
||||
authorizationDelegate: EndpointAuthorizableChannelTokenAuthorizationDelegate.forPrivateChannel(
|
||||
authorizationEndpoint: Uri.parse(baseUrl + '/broadcasting/auth'),
|
||||
headers: {
|
||||
'Authorization': 'Bearer $token',
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
void _subscribe() {
|
||||
_privateMessagesChannel?.subscribe();
|
||||
_privateNotificationChannel?.subscribe();
|
||||
}
|
||||
|
||||
void _unsubscribe() {
|
||||
_privateMessagesChannel?.unsubscribe();
|
||||
_privateNotificationChannel?.unsubscribe();
|
||||
}
|
||||
|
||||
void subscribeDirectChatChannel() {
|
||||
_privateDirectChatChannel?.subscribe();
|
||||
}
|
||||
|
||||
void unsubscribeDirectChatChannel() {
|
||||
_privateDirectChatChannel?.unsubscribe();
|
||||
}
|
||||
}
|
||||
15
lib/core/initialization_cubit/ws_service.dart
Normal file
15
lib/core/initialization_cubit/ws_service.dart
Normal file
@@ -0,0 +1,15 @@
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:eatvio_app/features/chat/models/websocket_info_model.dart';
|
||||
import 'package:retrofit/retrofit.dart';
|
||||
|
||||
part 'ws_service.g.dart';
|
||||
|
||||
|
||||
@RestApi()
|
||||
abstract class WsService {
|
||||
|
||||
factory WsService(Dio dio, {String baseUrl}) = _WsService;
|
||||
|
||||
@GET('/api/profile/ws/params')
|
||||
Future<WebsocketInfoModel> getWebsocket();
|
||||
}
|
||||
86
lib/core/initialization_cubit/ws_service.g.dart
Normal file
86
lib/core/initialization_cubit/ws_service.g.dart
Normal file
@@ -0,0 +1,86 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'ws_service.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// RetrofitGenerator
|
||||
// **************************************************************************
|
||||
|
||||
// ignore_for_file: unnecessary_brace_in_string_interps,no_leading_underscores_for_local_identifiers,unused_element,unnecessary_string_interpolations
|
||||
|
||||
class _WsService implements WsService {
|
||||
_WsService(
|
||||
this._dio, {
|
||||
this.baseUrl,
|
||||
this.errorLogger,
|
||||
});
|
||||
|
||||
final Dio _dio;
|
||||
|
||||
String? baseUrl;
|
||||
|
||||
final ParseErrorLogger? errorLogger;
|
||||
|
||||
@override
|
||||
Future<WebsocketInfoModel> getWebsocket() async {
|
||||
final _extra = <String, dynamic>{};
|
||||
final queryParameters = <String, dynamic>{};
|
||||
final _headers = <String, dynamic>{};
|
||||
const Map<String, dynamic>? _data = null;
|
||||
final _options = _setStreamType<WebsocketInfoModel>(Options(
|
||||
method: 'GET',
|
||||
headers: _headers,
|
||||
extra: _extra,
|
||||
)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/profile/ws/params',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(
|
||||
baseUrl: _combineBaseUrls(
|
||||
_dio.options.baseUrl,
|
||||
baseUrl,
|
||||
)));
|
||||
final _result = await _dio.fetch<Map<String, dynamic>>(_options);
|
||||
late WebsocketInfoModel _value;
|
||||
try {
|
||||
_value = WebsocketInfoModel.fromJson(_result.data!);
|
||||
} on Object catch (e, s) {
|
||||
errorLogger?.logError(e, s, _options);
|
||||
rethrow;
|
||||
}
|
||||
return _value;
|
||||
}
|
||||
|
||||
RequestOptions _setStreamType<T>(RequestOptions requestOptions) {
|
||||
if (T != dynamic &&
|
||||
!(requestOptions.responseType == ResponseType.bytes ||
|
||||
requestOptions.responseType == ResponseType.stream)) {
|
||||
if (T == String) {
|
||||
requestOptions.responseType = ResponseType.plain;
|
||||
} else {
|
||||
requestOptions.responseType = ResponseType.json;
|
||||
}
|
||||
}
|
||||
return requestOptions;
|
||||
}
|
||||
|
||||
String _combineBaseUrls(
|
||||
String dioBaseUrl,
|
||||
String? baseUrl,
|
||||
) {
|
||||
if (baseUrl == null || baseUrl.trim().isEmpty) {
|
||||
return dioBaseUrl;
|
||||
}
|
||||
|
||||
final url = Uri.parse(baseUrl);
|
||||
|
||||
if (url.isAbsolute) {
|
||||
return url.toString();
|
||||
}
|
||||
|
||||
return Uri.parse(dioBaseUrl).resolveUri(url).toString();
|
||||
}
|
||||
}
|
||||
@@ -1,12 +1,13 @@
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:eatvio_app/core/const.dart';
|
||||
import 'package:eatvio_app/core/initialization_cubit/ws_manager.dart';
|
||||
import 'package:eatvio_app/core/initialization_cubit/ws_service.dart';
|
||||
import 'package:eatvio_app/features/create_diet/presentation/cubit/create_diet_cubit.dart';
|
||||
import 'package:eatvio_app/features/create_diet/repositories/create_diet_repository.dart';
|
||||
import 'package:eatvio_app/features/create_diet/services/create_diet_service.dart';
|
||||
import 'package:eatvio_app/features/create_plan/presentation/cubit/create_plan_cubit.dart';
|
||||
import 'package:eatvio_app/features/diets/repositories/diet_repository.dart';
|
||||
import 'package:eatvio_app/features/diets/services/diet_service.dart';
|
||||
import 'package:eatvio_app/core/initialization_cubit/initialization_cubit.dart';
|
||||
import 'package:eatvio_app/features/blog_post_create/bloc/blog_post_create_cubit/blog_post_create_cubit.dart';
|
||||
import 'package:eatvio_app/features/blog_post_create/repositories/blog_post_repository.dart';
|
||||
import 'package:eatvio_app/features/blog_post_create/services/blog_post_service.dart';
|
||||
@@ -70,15 +71,15 @@ final sl = GetIt.instance;
|
||||
|
||||
Future<void> init() async {
|
||||
// Cubit singletons
|
||||
sl.registerLazySingleton<InitializationCubit>(() => InitializationCubit(chatRepository: sl()));
|
||||
sl.registerLazySingleton<WsManager>(() => WsManager(wsService: sl()));
|
||||
sl.registerLazySingleton<NewMessagesCubit>(() => NewMessagesCubit());
|
||||
sl.registerLazySingleton<NotificationsCubit>(() => NotificationsCubit());
|
||||
sl.registerLazySingleton<NotificationsCubit>(() => NotificationsCubit(wsManager: sl()));
|
||||
sl.registerLazySingleton<FeedCubit>(() => FeedCubit(feedRepository: sl()));
|
||||
sl.registerLazySingleton<ProfileAvatarCubit>(() => ProfileAvatarCubit(profileRepository: sl()));
|
||||
|
||||
// Cubit factories
|
||||
sl.registerFactory<RegistrationCubit>(() => RegistrationCubit(registrationRepository: sl()));
|
||||
sl.registerFactory<ChatRoomCubit>(() => ChatRoomCubit(chatRepository: sl(), initializationCubit: sl()));
|
||||
sl.registerFactory<ChatRoomCubit>(() => ChatRoomCubit(chatRepository: sl(), wsManager: sl()));
|
||||
sl.registerFactory<RecipesCubit>(() => RecipesCubit(feedRepository: sl(), recipeRepository: sl()));
|
||||
sl.registerFactory<CalendarCubit>(() => CalendarCubit(calendarRepository: sl()));
|
||||
sl.registerFactory<ProfileCubit>(() => ProfileCubit(profileRepository: sl(), chatRepository: sl()));
|
||||
@@ -140,6 +141,7 @@ Future<void> init() async {
|
||||
sl.registerLazySingleton<PlanService>(() => PlanService(sl()));
|
||||
sl.registerLazySingleton<MyDietsService>(() => MyDietsService(sl()));
|
||||
sl.registerLazySingleton<MyPlansService>(() => MyPlansService(sl()));
|
||||
sl.registerLazySingleton<WsService>(() => WsService(sl()));
|
||||
|
||||
// External
|
||||
sl.registerLazySingleton(
|
||||
|
||||
@@ -220,6 +220,12 @@ abstract class TextStyles {
|
||||
height: 1.255,
|
||||
);
|
||||
|
||||
static const textFS13FW400 = TextStyle(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w400,
|
||||
height: 1.255,
|
||||
);
|
||||
|
||||
static const textXSSemibold = TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w500,
|
||||
|
||||
@@ -186,6 +186,8 @@ class PrimaryColors {
|
||||
Color get red => Color(0xFFCD4141);
|
||||
|
||||
Color get transparentBlack => Color(0xFF1313264).withValues(alpha: 0.3);
|
||||
|
||||
Color get gray60004 => Color(0xFFD4DAE2).withValues(alpha: 0.2);
|
||||
}
|
||||
|
||||
PrimaryColors get appTheme => ThemeHelper().themeColor();
|
||||
|
||||
@@ -26,3 +26,15 @@ void showErrorToast(String message) {
|
||||
fontSize: 16.0,
|
||||
);
|
||||
}
|
||||
|
||||
void showSuccessToast(String message) {
|
||||
Fluttertoast.showToast(
|
||||
msg: message,
|
||||
toastLength: Toast.LENGTH_SHORT,
|
||||
gravity: ToastGravity.TOP,
|
||||
timeInSecForIosWeb: _toastDuration,
|
||||
backgroundColor: appTheme.greenA70001,
|
||||
textColor: appTheme.whiteA700,
|
||||
fontSize: 16.0,
|
||||
);
|
||||
}
|
||||
@@ -9,7 +9,11 @@ part of 'blog_post_service.dart';
|
||||
// ignore_for_file: unnecessary_brace_in_string_interps,no_leading_underscores_for_local_identifiers,unused_element,unnecessary_string_interpolations
|
||||
|
||||
class _BlogPostService implements BlogPostService {
|
||||
_BlogPostService(this._dio, {this.baseUrl, this.errorLogger});
|
||||
_BlogPostService(
|
||||
this._dio, {
|
||||
this.baseUrl,
|
||||
this.errorLogger,
|
||||
});
|
||||
|
||||
final Dio _dio;
|
||||
|
||||
@@ -23,21 +27,23 @@ class _BlogPostService implements BlogPostService {
|
||||
final queryParameters = <String, dynamic>{};
|
||||
final _headers = <String, dynamic>{};
|
||||
final _data = formData;
|
||||
final _options = _setStreamType<void>(
|
||||
Options(
|
||||
method: 'POST',
|
||||
headers: _headers,
|
||||
extra: _extra,
|
||||
contentType: 'multipart/form-data',
|
||||
)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/blogPosts/create',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(baseUrl: _combineBaseUrls(_dio.options.baseUrl, baseUrl)),
|
||||
);
|
||||
final _options = _setStreamType<void>(Options(
|
||||
method: 'POST',
|
||||
headers: _headers,
|
||||
extra: _extra,
|
||||
contentType: 'multipart/form-data',
|
||||
)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/blogPosts/create',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(
|
||||
baseUrl: _combineBaseUrls(
|
||||
_dio.options.baseUrl,
|
||||
baseUrl,
|
||||
)));
|
||||
await _dio.fetch<void>(_options);
|
||||
}
|
||||
|
||||
@@ -50,21 +56,23 @@ class _BlogPostService implements BlogPostService {
|
||||
final queryParameters = <String, dynamic>{};
|
||||
final _headers = <String, dynamic>{};
|
||||
final _data = formData;
|
||||
final _options = _setStreamType<void>(
|
||||
Options(
|
||||
method: 'POST',
|
||||
headers: _headers,
|
||||
extra: _extra,
|
||||
contentType: 'multipart/form-data',
|
||||
)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/blogPosts/update/${id}',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(baseUrl: _combineBaseUrls(_dio.options.baseUrl, baseUrl)),
|
||||
);
|
||||
final _options = _setStreamType<void>(Options(
|
||||
method: 'POST',
|
||||
headers: _headers,
|
||||
extra: _extra,
|
||||
contentType: 'multipart/form-data',
|
||||
)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/blogPosts/update/${id}',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(
|
||||
baseUrl: _combineBaseUrls(
|
||||
_dio.options.baseUrl,
|
||||
baseUrl,
|
||||
)));
|
||||
await _dio.fetch<void>(_options);
|
||||
}
|
||||
|
||||
@@ -74,16 +82,22 @@ class _BlogPostService implements BlogPostService {
|
||||
final queryParameters = <String, dynamic>{};
|
||||
final _headers = <String, dynamic>{};
|
||||
const Map<String, dynamic>? _data = null;
|
||||
final _options = _setStreamType<void>(
|
||||
Options(method: 'POST', headers: _headers, extra: _extra)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/blogPosts/delete/${id}',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(baseUrl: _combineBaseUrls(_dio.options.baseUrl, baseUrl)),
|
||||
);
|
||||
final _options = _setStreamType<void>(Options(
|
||||
method: 'POST',
|
||||
headers: _headers,
|
||||
extra: _extra,
|
||||
)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/blogPosts/delete/${id}',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(
|
||||
baseUrl: _combineBaseUrls(
|
||||
_dio.options.baseUrl,
|
||||
baseUrl,
|
||||
)));
|
||||
await _dio.fetch<void>(_options);
|
||||
}
|
||||
|
||||
@@ -100,7 +114,10 @@ class _BlogPostService implements BlogPostService {
|
||||
return requestOptions;
|
||||
}
|
||||
|
||||
String _combineBaseUrls(String dioBaseUrl, String? baseUrl) {
|
||||
String _combineBaseUrls(
|
||||
String dioBaseUrl,
|
||||
String? baseUrl,
|
||||
) {
|
||||
if (baseUrl == null || baseUrl.trim().isEmpty) {
|
||||
return dioBaseUrl;
|
||||
}
|
||||
|
||||
@@ -1,11 +1,16 @@
|
||||
import 'package:eatvio_app/core/initialization_cubit/ws_manager.dart';
|
||||
import 'package:eatvio_app/features/bottom_navigation_bar/presentation/bloc/notifications_cubit/notifications_state.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
|
||||
class NotificationsCubit extends Cubit<NotificationsState> {
|
||||
int _notificationsCount = 0;
|
||||
List<String> notifications = [];
|
||||
|
||||
NotificationsCubit() : super(const NotificationsState.empty());
|
||||
final WsManager wsManager;
|
||||
NotificationsCubit({required this.wsManager}) : super(const NotificationsState.empty()) {
|
||||
wsManager.newNotificationsStream?.listen((event) {
|
||||
incrementCounter(event.data);
|
||||
});
|
||||
}
|
||||
|
||||
incrementCounter(String data) {
|
||||
_notificationsCount++;
|
||||
|
||||
@@ -9,7 +9,11 @@ part of 'calendar_service.dart';
|
||||
// ignore_for_file: unnecessary_brace_in_string_interps,no_leading_underscores_for_local_identifiers,unused_element,unnecessary_string_interpolations
|
||||
|
||||
class _CalendarService implements CalendarService {
|
||||
_CalendarService(this._dio, {this.baseUrl, this.errorLogger});
|
||||
_CalendarService(
|
||||
this._dio, {
|
||||
this.baseUrl,
|
||||
this.errorLogger,
|
||||
});
|
||||
|
||||
final Dio _dio;
|
||||
|
||||
@@ -23,23 +27,27 @@ class _CalendarService implements CalendarService {
|
||||
final queryParameters = <String, dynamic>{};
|
||||
final _headers = <String, dynamic>{};
|
||||
const Map<String, dynamic>? _data = null;
|
||||
final _options = _setStreamType<List<CalendarModel>>(
|
||||
Options(method: 'GET', headers: _headers, extra: _extra)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/calendar/index',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(baseUrl: _combineBaseUrls(_dio.options.baseUrl, baseUrl)),
|
||||
);
|
||||
final _options = _setStreamType<List<CalendarModel>>(Options(
|
||||
method: 'GET',
|
||||
headers: _headers,
|
||||
extra: _extra,
|
||||
)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/calendar/index',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(
|
||||
baseUrl: _combineBaseUrls(
|
||||
_dio.options.baseUrl,
|
||||
baseUrl,
|
||||
)));
|
||||
final _result = await _dio.fetch<List<dynamic>>(_options);
|
||||
late List<CalendarModel> _value;
|
||||
try {
|
||||
_value = _result.data!
|
||||
.map(
|
||||
(dynamic i) => CalendarModel.fromJson(i as Map<String, dynamic>),
|
||||
)
|
||||
.map((dynamic i) => CalendarModel.fromJson(i as Map<String, dynamic>))
|
||||
.toList();
|
||||
} on Object catch (e, s) {
|
||||
errorLogger?.logError(e, s, _options);
|
||||
@@ -61,7 +69,10 @@ class _CalendarService implements CalendarService {
|
||||
return requestOptions;
|
||||
}
|
||||
|
||||
String _combineBaseUrls(String dioBaseUrl, String? baseUrl) {
|
||||
String _combineBaseUrls(
|
||||
String dioBaseUrl,
|
||||
String? baseUrl,
|
||||
) {
|
||||
if (baseUrl == null || baseUrl.trim().isEmpty) {
|
||||
return dioBaseUrl;
|
||||
}
|
||||
|
||||
@@ -2,13 +2,9 @@ import 'dart:convert';
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:audioplayers/audioplayers.dart';
|
||||
import 'package:dart_pusher_channels/dart_pusher_channels.dart';
|
||||
import 'package:easy_debounce/easy_debounce.dart';
|
||||
import 'package:eatvio_app/core/const.dart';
|
||||
import 'package:eatvio_app/core/image_compressing/image_compress_utility.dart';
|
||||
import 'package:eatvio_app/core/initialization_cubit/initialization_cubit.dart';
|
||||
import 'package:eatvio_app/core/initialization_cubit/initialization_state.dart';
|
||||
import 'package:eatvio_app/core/token_storage.dart';
|
||||
import 'package:eatvio_app/core/initialization_cubit/ws_manager.dart';
|
||||
import 'package:eatvio_app/features/chat/models/chat_message_model.dart';
|
||||
import 'package:eatvio_app/features/chat/presentation/bloc/chat_room_cubit/chat_room_state.dart';
|
||||
import 'package:eatvio_app/features/chat/repositories/chat_repository.dart';
|
||||
@@ -16,41 +12,42 @@ import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
|
||||
class ChatRoomCubit extends Cubit<ChatRoomState> {
|
||||
final ChatRepository chatRepository;
|
||||
final InitializationCubit initializationCubit;
|
||||
final WsManager wsManager;
|
||||
|
||||
int currentPage = 1;
|
||||
late final int lastPage;
|
||||
bool isLoading = false;
|
||||
|
||||
late final PusherChannelsClient client;
|
||||
late final PrivateChannel privateChatChannel;
|
||||
|
||||
ChatRoomCubit({
|
||||
required this.chatRepository,
|
||||
required this.initializationCubit,
|
||||
required this.wsManager,
|
||||
}) : super(ChatRoomState.loading());
|
||||
|
||||
loadNextPage(String chatId) async {
|
||||
if (currentPage < lastPage && !isLoading) {
|
||||
isLoading = true;
|
||||
|
||||
emit(ChatRoomState.loaded(
|
||||
chatRoom: (state as ChatRoomStateLoaded).chatRoom,
|
||||
chatMessages: (state as ChatRoomStateLoaded).chatMessages,
|
||||
isTyping: (state as ChatRoomStateLoaded).isTyping,
|
||||
isLoading: isLoading,
|
||||
),);
|
||||
emit(
|
||||
ChatRoomState.loaded(
|
||||
chatRoom: (state as ChatRoomStateLoaded).chatRoom,
|
||||
chatMessages: (state as ChatRoomStateLoaded).chatMessages,
|
||||
isTyping: (state as ChatRoomStateLoaded).isTyping,
|
||||
isLoading: isLoading,
|
||||
),
|
||||
);
|
||||
|
||||
try {
|
||||
final chatMessages = await chatRepository.getChatMessages(chatId, currentPage + 1);
|
||||
|
||||
isLoading = false;
|
||||
emit(ChatRoomState.loaded(
|
||||
chatRoom: (state as ChatRoomStateLoaded).chatRoom,
|
||||
chatMessages: [...(state as ChatRoomStateLoaded).chatMessages, ...chatMessages.messagesList],
|
||||
isTyping: (state as ChatRoomStateLoaded).isTyping,
|
||||
isLoading: isLoading,
|
||||
),);
|
||||
emit(
|
||||
ChatRoomState.loaded(
|
||||
chatRoom: (state as ChatRoomStateLoaded).chatRoom,
|
||||
chatMessages: [...(state as ChatRoomStateLoaded).chatMessages, ...chatMessages.messagesList],
|
||||
isTyping: (state as ChatRoomStateLoaded).isTyping,
|
||||
isLoading: isLoading,
|
||||
),
|
||||
);
|
||||
|
||||
currentPage++;
|
||||
} catch (e) {
|
||||
@@ -66,38 +63,29 @@ class ChatRoomCubit extends Cubit<ChatRoomState> {
|
||||
final chatMessages = await chatRepository.getChatMessages(chatId, currentPage);
|
||||
lastPage = chatMessages.meta.lastPage;
|
||||
|
||||
await _subscribeToChatChannel(initCubit: initializationCubit, chatId: chatId);
|
||||
await _subscribeToChatChannel(chatId: chatId);
|
||||
|
||||
emit(ChatRoomState.loaded(
|
||||
chatRoom: chatRoom,
|
||||
chatMessages: chatMessages.messagesList,
|
||||
isTyping: false,
|
||||
isLoading: isLoading,
|
||||
),);
|
||||
emit(
|
||||
ChatRoomState.loaded(
|
||||
chatRoom: chatRoom,
|
||||
chatMessages: chatMessages.messagesList,
|
||||
isTyping: false,
|
||||
isLoading: isLoading,
|
||||
),
|
||||
);
|
||||
} catch (e) {
|
||||
emit(ChatRoomState.error(errorMessage: 'Ошибка получеия данных'));
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _subscribeToChatChannel({
|
||||
required InitializationCubit initCubit,
|
||||
required String chatId,
|
||||
}) async {
|
||||
client = (initCubit.state as InitializationStateSuccess).client;
|
||||
|
||||
privateChatChannel = await client.privateChannel(
|
||||
'private-direct-chat.$chatId',
|
||||
authorizationDelegate: EndpointAuthorizableChannelTokenAuthorizationDelegate.forPrivateChannel(
|
||||
authorizationEndpoint: Uri.parse(baseUrl + '/broadcasting/auth'),
|
||||
headers: {
|
||||
'Authorization': 'Bearer ${await TokenStorage.getTokenFromStorage()}',
|
||||
},
|
||||
),
|
||||
);
|
||||
|
||||
privateChatChannel.subscribe();
|
||||
|
||||
privateChatChannel.bind('App\\Events\\ChatMessageUpdated').listen((event) {
|
||||
final client = wsManager.client;
|
||||
if (client == null) return;
|
||||
await wsManager.initPrivateDirectChatChannel(chatId);
|
||||
wsManager.subscribeDirectChatChannel();
|
||||
wsManager.directChatStream?.listen((event) {
|
||||
AudioPlayer().play((AssetSource('audio/recive_message.wav')));
|
||||
List<ChatMessageModel> messagesList = [
|
||||
ChatMessageModel.fromJson(jsonDecode(event.data)['message']),
|
||||
@@ -113,7 +101,7 @@ class ChatRoomCubit extends Cubit<ChatRoomState> {
|
||||
);
|
||||
});
|
||||
|
||||
privateChatChannel.bind('client-typing').listen((event) {
|
||||
wsManager.clientTypingStream?.listen((event) {
|
||||
emit(
|
||||
ChatRoomState.loaded(
|
||||
chatRoom: (state as ChatRoomStateLoaded).chatRoom,
|
||||
@@ -152,7 +140,7 @@ class ChatRoomCubit extends Cubit<ChatRoomState> {
|
||||
|
||||
@override
|
||||
Future<void> close() async {
|
||||
privateChatChannel.unsubscribe();
|
||||
wsManager.unsubscribeDirectChatChannel();
|
||||
super.close();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import 'dart:io';
|
||||
import 'dart:math';
|
||||
|
||||
import 'package:eatvio_app/core/widgets/loader.dart';
|
||||
import 'package:eatvio_app/features/chat/presentation/bloc/chat_room_cubit/chat_room_cubit.dart';
|
||||
@@ -78,6 +79,7 @@ class _ChatScreenState extends State<ChatScreen> {
|
||||
resizeToAvoidBottomInset: true,
|
||||
appBar: AppBar(
|
||||
titleSpacing: 0,
|
||||
backgroundColor: appTheme.gray100,
|
||||
centerTitle: false,
|
||||
title: Row(
|
||||
children: [
|
||||
@@ -136,7 +138,7 @@ class _ChatScreenState extends State<ChatScreen> {
|
||||
children: [
|
||||
Expanded(
|
||||
child: Container(
|
||||
color: Color(0xFFF0F2F5),
|
||||
color: appTheme.whiteA700,
|
||||
width: double.maxFinite,
|
||||
child: CustomScrollView(
|
||||
physics: BouncingScrollPhysics(),
|
||||
@@ -149,20 +151,16 @@ class _ChatScreenState extends State<ChatScreen> {
|
||||
delegate: SliverChildBuilderDelegate(
|
||||
(context, index) {
|
||||
if (index < state.chatMessages.length) {
|
||||
return Column(
|
||||
children: [
|
||||
if ((index + 1 != state.chatMessages.length &&
|
||||
DateTime.parse(state.chatMessages[index].updatedAt).day !=
|
||||
DateTime.parse(state.chatMessages[index + 1].updatedAt).day) ||
|
||||
index + 1 == state.chatMessages.length)
|
||||
_messageDate(state.chatMessages[index].updatedAt),
|
||||
ChatBubbleWidget(
|
||||
sendTime: state.chatMessages[index].updatedAt,
|
||||
text: state.chatMessages[index].data.trim(),
|
||||
isCurrentUser: state.chatRoom.users['to_chat_user']!.id != state.chatMessages[index].authorId,
|
||||
mediaData: state.chatMessages[index].mediaData ?? [],
|
||||
),
|
||||
],
|
||||
if ((index + 1 != state.chatMessages.length &&
|
||||
DateTime.parse(state.chatMessages[index].updatedAt).day != DateTime.parse(state.chatMessages[index + 1].updatedAt).day) ||
|
||||
index + 1 == state.chatMessages.length) {
|
||||
return _messageDate(state.chatMessages[index].updatedAt);
|
||||
}
|
||||
return ChatBubbleWidget(
|
||||
sendTime: state.chatMessages[index].updatedAt,
|
||||
text: state.chatMessages[index].data.trim(),
|
||||
isCurrentUser: state.chatRoom.users['to_chat_user']!.id != state.chatMessages[index].authorId,
|
||||
mediaData: state.chatMessages[index].mediaData ?? [],
|
||||
);
|
||||
} else {
|
||||
return Padding(
|
||||
@@ -181,13 +179,6 @@ class _ChatScreenState extends State<ChatScreen> {
|
||||
),
|
||||
Container(
|
||||
padding: EdgeInsets.symmetric(vertical: 8),
|
||||
decoration: BoxDecoration(
|
||||
border: Border(
|
||||
top: BorderSide(
|
||||
color: Colors.black.withValues(alpha: 0.1),
|
||||
),
|
||||
),
|
||||
),
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.end,
|
||||
children: [
|
||||
@@ -231,57 +222,60 @@ class _ChatScreenState extends State<ChatScreen> {
|
||||
},
|
||||
customBorder: CircleBorder(),
|
||||
child: Ink(
|
||||
height: 32,
|
||||
width: 32,
|
||||
height: 40,
|
||||
width: 40,
|
||||
child: Transform.rotate(
|
||||
angle: 3.8,
|
||||
angle: pi / 4,
|
||||
child: Icon(
|
||||
Icons.attach_file_rounded,
|
||||
size: 24,
|
||||
size: 30,
|
||||
color: Color(0xFF858E99),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(width: 8),
|
||||
SizedBox(
|
||||
width: MediaQuery.of(context).size.width - 96,
|
||||
child: TextFormField(
|
||||
controller: textEditingController,
|
||||
maxLines: 5,
|
||||
minLines: 1,
|
||||
keyboardType: TextInputType.multiline,
|
||||
style: TextStyle(fontSize: 16, fontWeight: FontWeight.w400, color: Colors.black, height: 1),
|
||||
decoration: InputDecoration(
|
||||
isDense: true,
|
||||
contentPadding: EdgeInsets.symmetric(horizontal: 16, vertical: 8),
|
||||
hintText: 'Сообщение',
|
||||
hintStyle: TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w400,
|
||||
height: 1,
|
||||
color: Color(0xFFAEAEB2),
|
||||
),
|
||||
filled: true,
|
||||
border: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
borderSide: BorderSide(
|
||||
color: Color(0xFFD1D1D6),
|
||||
width: 1,
|
||||
Expanded(
|
||||
child: SizedBox(
|
||||
height: 40,
|
||||
child: TextFormField(
|
||||
expands: true,
|
||||
controller: textEditingController,
|
||||
maxLines: null,
|
||||
minLines: null,
|
||||
keyboardType: TextInputType.multiline,
|
||||
style: TextStyle(fontSize: 16, fontWeight: FontWeight.w400, color: Colors.black, height: 1),
|
||||
decoration: InputDecoration(
|
||||
isDense: true,
|
||||
contentPadding: EdgeInsets.symmetric(horizontal: 16, vertical: 10),
|
||||
hintText: 'Сообщение',
|
||||
hintStyle: TextStyle(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w400,
|
||||
height: 1,
|
||||
color: Color(0xFFAEAEB2),
|
||||
),
|
||||
),
|
||||
enabledBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
borderSide: BorderSide(
|
||||
color: Color(0xFFD1D1D6),
|
||||
width: 1,
|
||||
filled: true,
|
||||
border: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(100),
|
||||
borderSide: BorderSide(
|
||||
color: Color(0xFFD1D1D6),
|
||||
width: 1,
|
||||
),
|
||||
),
|
||||
),
|
||||
focusedBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
borderSide: BorderSide(
|
||||
color: Color(0xFFD1D1D6),
|
||||
width: 1,
|
||||
enabledBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(100),
|
||||
borderSide: BorderSide(
|
||||
color: Color(0xFFD1D1D6),
|
||||
width: 1,
|
||||
),
|
||||
),
|
||||
focusedBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(100),
|
||||
borderSide: BorderSide(
|
||||
color: Color(0xFFD1D1D6),
|
||||
width: 1,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
@@ -306,11 +300,11 @@ class _ChatScreenState extends State<ChatScreen> {
|
||||
color: appTheme.blueA400,
|
||||
shape: BoxShape.circle,
|
||||
),
|
||||
height: 32,
|
||||
width: 32,
|
||||
height: 40,
|
||||
width: 40,
|
||||
child: Icon(
|
||||
Icons.arrow_upward_rounded,
|
||||
size: 20,
|
||||
size: 24,
|
||||
color: Colors.white,
|
||||
),
|
||||
),
|
||||
@@ -326,16 +320,18 @@ class _ChatScreenState extends State<ChatScreen> {
|
||||
}
|
||||
|
||||
_messageDate(String date) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 8),
|
||||
child: Text(
|
||||
DateFormat.MMMMd('RU').format(
|
||||
DateTime.parse(date),
|
||||
),
|
||||
style: const TextStyle(
|
||||
height: 1,
|
||||
color: Color(0xFF8393A1),
|
||||
fontWeight: FontWeight.w500,
|
||||
return Center(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 8),
|
||||
child: Text(
|
||||
DateFormat.yMMMMd('RU').format(
|
||||
DateTime.parse(date),
|
||||
),
|
||||
style: const TextStyle(
|
||||
height: 1,
|
||||
color: Color(0xFF8393A1),
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import 'package:cached_network_image/cached_network_image.dart';
|
||||
import 'package:dismissible_page/dismissible_page.dart';
|
||||
import 'package:eatvio_app/core/const.dart';
|
||||
import 'package:eatvio_app/core/theme/custom_text_style.dart';
|
||||
import 'package:eatvio_app/core/theme/theme_helper.dart';
|
||||
import 'package:eatvio_app/core/utils/date_time_utils.dart';
|
||||
import 'package:eatvio_app/features/chat/presentation/pages/photo_view_screen.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
@@ -28,7 +30,7 @@ class ChatBubbleWidget extends StatelessWidget {
|
||||
alignment: isCurrentUser ? Alignment.centerRight : Alignment.centerLeft,
|
||||
child: DecoratedBox(
|
||||
decoration: BoxDecoration(
|
||||
color: isCurrentUser ? Color(0xFF7F9CF5) : Colors.white,
|
||||
color: isCurrentUser ? appTheme.gray50 : appTheme.gray60004,
|
||||
borderRadius: mediaData.length > 0
|
||||
? BorderRadius.circular(24)
|
||||
: BorderRadius.horizontal(
|
||||
@@ -108,15 +110,15 @@ class ChatBubbleWidget extends StatelessWidget {
|
||||
if (text.isNotEmpty)
|
||||
Text(
|
||||
text,
|
||||
style: TextStyle(color: isCurrentUser ? Colors.white : Color(0xFF323F4B), height: 1),
|
||||
style: TextStyles.textFS13FW400.copyWith(color: appTheme.black),
|
||||
),
|
||||
SizedBox(height: 4),
|
||||
SizedBox(height: 8),
|
||||
Padding(
|
||||
padding: mediaData.length > 0 ? const EdgeInsets.only(right: 8, top: 4, left: 8) : EdgeInsets.zero,
|
||||
child: Text(
|
||||
DateTime.parse(sendTime).format('hh:mm'),
|
||||
style: TextStyle(
|
||||
color: isCurrentUser ? Colors.white.withValues(alpha: 0.4) : Color(0xFF323F4B).withValues(alpha: 0.4),
|
||||
color: Color(0xFF7B8794),
|
||||
height: 1,
|
||||
fontSize: 10,
|
||||
),
|
||||
|
||||
@@ -4,7 +4,6 @@ import 'package:dio/dio.dart';
|
||||
import 'package:eatvio_app/features/chat/models/chat_messages_model.dart';
|
||||
import 'package:eatvio_app/features/chat/models/chat_room_model.dart';
|
||||
import 'package:eatvio_app/features/chat/models/chat_room_preview_model.dart';
|
||||
import 'package:eatvio_app/features/chat/models/websocket_info_model.dart';
|
||||
import 'package:eatvio_app/features/chat/services/chat_service.dart';
|
||||
import 'package:http_parser/http_parser.dart';
|
||||
|
||||
@@ -67,15 +66,7 @@ class ChatRepository {
|
||||
} catch (e) {
|
||||
rethrow;
|
||||
}
|
||||
}
|
||||
|
||||
Future<WebsocketInfoModel> getWebsocket() async {
|
||||
try {
|
||||
return (await chatService.getWebsocket());
|
||||
} catch (e) {
|
||||
rethrow;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Future<ChatRoomModel> getChatRoomIdByUserSlug({required String slug}) async {
|
||||
try {
|
||||
|
||||
@@ -2,7 +2,6 @@ import 'package:dio/dio.dart';
|
||||
import 'package:eatvio_app/features/chat/models/chat_messages_model.dart';
|
||||
import 'package:eatvio_app/features/chat/models/chat_room_model.dart';
|
||||
import 'package:eatvio_app/features/chat/models/chat_room_preview_model.dart';
|
||||
import 'package:eatvio_app/features/chat/models/websocket_info_model.dart';
|
||||
import 'package:retrofit/retrofit.dart';
|
||||
|
||||
part 'chat_service.g.dart';
|
||||
@@ -35,9 +34,6 @@ abstract class ChatService {
|
||||
@Path() required int page,
|
||||
});
|
||||
|
||||
@GET('/api/profile/ws/params')
|
||||
Future<WebsocketInfoModel> getWebsocket();
|
||||
|
||||
@GET('/api/chat/get_by_user/{user}')
|
||||
Future<ChatRoomModel> getChatRoomIdByUserSlug({
|
||||
@Path() required String user,
|
||||
|
||||
@@ -9,7 +9,11 @@ part of 'chat_service.dart';
|
||||
// ignore_for_file: unnecessary_brace_in_string_interps,no_leading_underscores_for_local_identifiers,unused_element,unnecessary_string_interpolations
|
||||
|
||||
class _ChatService implements ChatService {
|
||||
_ChatService(this._dio, {this.baseUrl, this.errorLogger});
|
||||
_ChatService(
|
||||
this._dio, {
|
||||
this.baseUrl,
|
||||
this.errorLogger,
|
||||
});
|
||||
|
||||
final Dio _dio;
|
||||
|
||||
@@ -24,16 +28,22 @@ class _ChatService implements ChatService {
|
||||
queryParameters.removeWhere((k, v) => v == null);
|
||||
final _headers = <String, dynamic>{};
|
||||
const Map<String, dynamic>? _data = null;
|
||||
final _options = _setStreamType<ChatRoomPreviewModel>(
|
||||
Options(method: 'GET', headers: _headers, extra: _extra)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/chat/index',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(baseUrl: _combineBaseUrls(_dio.options.baseUrl, baseUrl)),
|
||||
);
|
||||
final _options = _setStreamType<ChatRoomPreviewModel>(Options(
|
||||
method: 'GET',
|
||||
headers: _headers,
|
||||
extra: _extra,
|
||||
)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/chat/index',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(
|
||||
baseUrl: _combineBaseUrls(
|
||||
_dio.options.baseUrl,
|
||||
baseUrl,
|
||||
)));
|
||||
final _result = await _dio.fetch<Map<String, dynamic>>(_options);
|
||||
late ChatRoomPreviewModel _value;
|
||||
try {
|
||||
@@ -51,23 +61,27 @@ class _ChatService implements ChatService {
|
||||
final queryParameters = <String, dynamic>{};
|
||||
final _headers = <String, dynamic>{};
|
||||
const Map<String, dynamic>? _data = null;
|
||||
final _options = _setStreamType<Map<String, ChatRoomModel>>(
|
||||
Options(method: 'GET', headers: _headers, extra: _extra)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/chat/show/${id}',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(baseUrl: _combineBaseUrls(_dio.options.baseUrl, baseUrl)),
|
||||
);
|
||||
final _options = _setStreamType<Map<String, ChatRoomModel>>(Options(
|
||||
method: 'GET',
|
||||
headers: _headers,
|
||||
extra: _extra,
|
||||
)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/chat/show/${id}',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(
|
||||
baseUrl: _combineBaseUrls(
|
||||
_dio.options.baseUrl,
|
||||
baseUrl,
|
||||
)));
|
||||
final _result = await _dio.fetch<Map<String, dynamic>>(_options);
|
||||
late Map<String, ChatRoomModel> _value;
|
||||
try {
|
||||
_value = _result.data!.map(
|
||||
(k, dynamic v) =>
|
||||
MapEntry(k, ChatRoomModel.fromJson(v as Map<String, dynamic>)),
|
||||
);
|
||||
_value = _result.data!.map((k, dynamic v) =>
|
||||
MapEntry(k, ChatRoomModel.fromJson(v as Map<String, dynamic>)));
|
||||
} on Object catch (e, s) {
|
||||
errorLogger?.logError(e, s, _options);
|
||||
rethrow;
|
||||
@@ -87,26 +101,31 @@ class _ChatService implements ChatService {
|
||||
final _headers = <String, dynamic>{};
|
||||
final _data = FormData();
|
||||
if (data != null) {
|
||||
_data.fields.add(MapEntry('data', data));
|
||||
_data.fields.add(MapEntry(
|
||||
'data',
|
||||
data,
|
||||
));
|
||||
}
|
||||
if (media_data != null) {
|
||||
_data.files.addAll(media_data.map((i) => MapEntry('media_data[]', i)));
|
||||
}
|
||||
final _options = _setStreamType<void>(
|
||||
Options(
|
||||
method: 'POST',
|
||||
headers: _headers,
|
||||
extra: _extra,
|
||||
contentType: 'multipart/form-data',
|
||||
)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/chat/${id}/message/send',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(baseUrl: _combineBaseUrls(_dio.options.baseUrl, baseUrl)),
|
||||
);
|
||||
final _options = _setStreamType<void>(Options(
|
||||
method: 'POST',
|
||||
headers: _headers,
|
||||
extra: _extra,
|
||||
contentType: 'multipart/form-data',
|
||||
)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/chat/${id}/message/send',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(
|
||||
baseUrl: _combineBaseUrls(
|
||||
_dio.options.baseUrl,
|
||||
baseUrl,
|
||||
)));
|
||||
await _dio.fetch<void>(_options);
|
||||
}
|
||||
|
||||
@@ -119,16 +138,22 @@ class _ChatService implements ChatService {
|
||||
final queryParameters = <String, dynamic>{};
|
||||
final _headers = <String, dynamic>{};
|
||||
const Map<String, dynamic>? _data = null;
|
||||
final _options = _setStreamType<ChatMessagesModel>(
|
||||
Options(method: 'GET', headers: _headers, extra: _extra)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/chat/show/${id}/messages?page=${page}',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(baseUrl: _combineBaseUrls(_dio.options.baseUrl, baseUrl)),
|
||||
);
|
||||
final _options = _setStreamType<ChatMessagesModel>(Options(
|
||||
method: 'GET',
|
||||
headers: _headers,
|
||||
extra: _extra,
|
||||
)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/chat/show/${id}/messages?page=${page}',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(
|
||||
baseUrl: _combineBaseUrls(
|
||||
_dio.options.baseUrl,
|
||||
baseUrl,
|
||||
)));
|
||||
final _result = await _dio.fetch<Map<String, dynamic>>(_options);
|
||||
late ChatMessagesModel _value;
|
||||
try {
|
||||
@@ -140,49 +165,28 @@ class _ChatService implements ChatService {
|
||||
return _value;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<WebsocketInfoModel> getWebsocket() async {
|
||||
final _extra = <String, dynamic>{};
|
||||
final queryParameters = <String, dynamic>{};
|
||||
final _headers = <String, dynamic>{};
|
||||
const Map<String, dynamic>? _data = null;
|
||||
final _options = _setStreamType<WebsocketInfoModel>(
|
||||
Options(method: 'GET', headers: _headers, extra: _extra)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/profile/ws/params',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(baseUrl: _combineBaseUrls(_dio.options.baseUrl, baseUrl)),
|
||||
);
|
||||
final _result = await _dio.fetch<Map<String, dynamic>>(_options);
|
||||
late WebsocketInfoModel _value;
|
||||
try {
|
||||
_value = WebsocketInfoModel.fromJson(_result.data!);
|
||||
} on Object catch (e, s) {
|
||||
errorLogger?.logError(e, s, _options);
|
||||
rethrow;
|
||||
}
|
||||
return _value;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<ChatRoomModel> getChatRoomIdByUserSlug({required String user}) async {
|
||||
final _extra = <String, dynamic>{};
|
||||
final queryParameters = <String, dynamic>{};
|
||||
final _headers = <String, dynamic>{};
|
||||
const Map<String, dynamic>? _data = null;
|
||||
final _options = _setStreamType<ChatRoomModel>(
|
||||
Options(method: 'GET', headers: _headers, extra: _extra)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/chat/get_by_user/${user}',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(baseUrl: _combineBaseUrls(_dio.options.baseUrl, baseUrl)),
|
||||
);
|
||||
final _options = _setStreamType<ChatRoomModel>(Options(
|
||||
method: 'GET',
|
||||
headers: _headers,
|
||||
extra: _extra,
|
||||
)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/chat/get_by_user/${user}',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(
|
||||
baseUrl: _combineBaseUrls(
|
||||
_dio.options.baseUrl,
|
||||
baseUrl,
|
||||
)));
|
||||
final _result = await _dio.fetch<Map<String, dynamic>>(_options);
|
||||
late ChatRoomModel _value;
|
||||
try {
|
||||
@@ -207,7 +211,10 @@ class _ChatService implements ChatService {
|
||||
return requestOptions;
|
||||
}
|
||||
|
||||
String _combineBaseUrls(String dioBaseUrl, String? baseUrl) {
|
||||
String _combineBaseUrls(
|
||||
String dioBaseUrl,
|
||||
String? baseUrl,
|
||||
) {
|
||||
if (baseUrl == null || baseUrl.trim().isEmpty) {
|
||||
return dioBaseUrl;
|
||||
}
|
||||
|
||||
@@ -9,7 +9,11 @@ part of 'consultant_service.dart';
|
||||
// ignore_for_file: unnecessary_brace_in_string_interps,no_leading_underscores_for_local_identifiers,unused_element,unnecessary_string_interpolations
|
||||
|
||||
class _ConsultantService implements ConsultantService {
|
||||
_ConsultantService(this._dio, {this.baseUrl, this.errorLogger});
|
||||
_ConsultantService(
|
||||
this._dio, {
|
||||
this.baseUrl,
|
||||
this.errorLogger,
|
||||
});
|
||||
|
||||
final Dio _dio;
|
||||
|
||||
@@ -18,23 +22,28 @@ class _ConsultantService implements ConsultantService {
|
||||
final ParseErrorLogger? errorLogger;
|
||||
|
||||
@override
|
||||
Future<void> consultantRegistration({
|
||||
required ConsultantProfileModel consultantModel,
|
||||
}) async {
|
||||
Future<void> consultantRegistration(
|
||||
{required ConsultantProfileModel consultantModel}) async {
|
||||
final _extra = <String, dynamic>{};
|
||||
final queryParameters = <String, dynamic>{};
|
||||
final _headers = <String, dynamic>{};
|
||||
final _data = consultantModel;
|
||||
final _options = _setStreamType<void>(
|
||||
Options(method: 'POST', headers: _headers, extra: _extra)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/consultant_request/registration',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(baseUrl: _combineBaseUrls(_dio.options.baseUrl, baseUrl)),
|
||||
);
|
||||
final _options = _setStreamType<void>(Options(
|
||||
method: 'POST',
|
||||
headers: _headers,
|
||||
extra: _extra,
|
||||
)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/consultant_request/registration',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(
|
||||
baseUrl: _combineBaseUrls(
|
||||
_dio.options.baseUrl,
|
||||
baseUrl,
|
||||
)));
|
||||
await _dio.fetch<void>(_options);
|
||||
}
|
||||
|
||||
@@ -48,21 +57,23 @@ class _ConsultantService implements ConsultantService {
|
||||
if (photos != null) {
|
||||
_data.files.addAll(photos.map((i) => MapEntry('photos[]', i)));
|
||||
}
|
||||
final _options = _setStreamType<List<String>>(
|
||||
Options(
|
||||
method: 'POST',
|
||||
headers: _headers,
|
||||
extra: _extra,
|
||||
contentType: 'multipart/form-data',
|
||||
)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/consultant_request/photos/upload',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(baseUrl: _combineBaseUrls(_dio.options.baseUrl, baseUrl)),
|
||||
);
|
||||
final _options = _setStreamType<List<String>>(Options(
|
||||
method: 'POST',
|
||||
headers: _headers,
|
||||
extra: _extra,
|
||||
contentType: 'multipart/form-data',
|
||||
)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/consultant_request/photos/upload',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(
|
||||
baseUrl: _combineBaseUrls(
|
||||
_dio.options.baseUrl,
|
||||
baseUrl,
|
||||
)));
|
||||
final _result = await _dio.fetch<List<dynamic>>(_options);
|
||||
late List<String> _value;
|
||||
try {
|
||||
@@ -87,7 +98,10 @@ class _ConsultantService implements ConsultantService {
|
||||
return requestOptions;
|
||||
}
|
||||
|
||||
String _combineBaseUrls(String dioBaseUrl, String? baseUrl) {
|
||||
String _combineBaseUrls(
|
||||
String dioBaseUrl,
|
||||
String? baseUrl,
|
||||
) {
|
||||
if (baseUrl == null || baseUrl.trim().isEmpty) {
|
||||
return dioBaseUrl;
|
||||
}
|
||||
|
||||
@@ -9,7 +9,11 @@ part of 'create_diet_service.dart';
|
||||
// ignore_for_file: unnecessary_brace_in_string_interps,no_leading_underscores_for_local_identifiers,unused_element,unnecessary_string_interpolations
|
||||
|
||||
class _CreateDietService implements CreateDietService {
|
||||
_CreateDietService(this._dio, {this.baseUrl, this.errorLogger});
|
||||
_CreateDietService(
|
||||
this._dio, {
|
||||
this.baseUrl,
|
||||
this.errorLogger,
|
||||
});
|
||||
|
||||
final Dio _dio;
|
||||
|
||||
@@ -35,57 +39,81 @@ class _CreateDietService implements CreateDietService {
|
||||
final _headers = <String, dynamic>{};
|
||||
final _data = FormData();
|
||||
if (name != null) {
|
||||
_data.fields.add(MapEntry('name', name));
|
||||
_data.fields.add(MapEntry(
|
||||
'name',
|
||||
name,
|
||||
));
|
||||
}
|
||||
if (duration != null) {
|
||||
_data.fields.add(MapEntry('duration', duration.toString()));
|
||||
_data.fields.add(MapEntry(
|
||||
'duration',
|
||||
duration.toString(),
|
||||
));
|
||||
}
|
||||
if (state != null) {
|
||||
_data.fields.add(MapEntry('state', state));
|
||||
_data.fields.add(MapEntry(
|
||||
'state',
|
||||
state,
|
||||
));
|
||||
}
|
||||
if (meatType != null) {
|
||||
_data.fields.add(MapEntry('type[meat]', meatType));
|
||||
_data.fields.add(MapEntry(
|
||||
'type[meat]',
|
||||
meatType,
|
||||
));
|
||||
}
|
||||
if (carbType != null) {
|
||||
_data.fields.add(MapEntry('type[carb]', carbType));
|
||||
_data.fields.add(MapEntry(
|
||||
'type[carb]',
|
||||
carbType,
|
||||
));
|
||||
}
|
||||
if (vegType != null) {
|
||||
_data.fields.add(MapEntry('type[veg]', vegType));
|
||||
_data.fields.add(MapEntry(
|
||||
'type[veg]',
|
||||
vegType,
|
||||
));
|
||||
}
|
||||
if (lightType != null) {
|
||||
_data.fields.add(MapEntry('type[light]', lightType));
|
||||
_data.fields.add(MapEntry(
|
||||
'type[light]',
|
||||
lightType,
|
||||
));
|
||||
}
|
||||
if (details != null) {
|
||||
_data.fields.add(MapEntry('details', details));
|
||||
_data.fields.add(MapEntry(
|
||||
'details',
|
||||
details,
|
||||
));
|
||||
}
|
||||
if (image != null) {
|
||||
if (image != null) {
|
||||
_data.files.add(
|
||||
MapEntry(
|
||||
'image',
|
||||
MultipartFile.fromFileSync(
|
||||
image.path,
|
||||
filename: image.path.split(Platform.pathSeparator).last,
|
||||
),
|
||||
_data.files.add(MapEntry(
|
||||
'image',
|
||||
MultipartFile.fromFileSync(
|
||||
image.path,
|
||||
filename: image.path.split(Platform.pathSeparator).last,
|
||||
),
|
||||
);
|
||||
));
|
||||
}
|
||||
}
|
||||
final _options = _setStreamType<CreatedDiet>(
|
||||
Options(
|
||||
method: 'POST',
|
||||
headers: _headers,
|
||||
extra: _extra,
|
||||
contentType: 'multipart/form-data',
|
||||
)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/diets/create',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(baseUrl: _combineBaseUrls(_dio.options.baseUrl, baseUrl)),
|
||||
);
|
||||
final _options = _setStreamType<CreatedDiet>(Options(
|
||||
method: 'POST',
|
||||
headers: _headers,
|
||||
extra: _extra,
|
||||
contentType: 'multipart/form-data',
|
||||
)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/diets/create',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(
|
||||
baseUrl: _combineBaseUrls(
|
||||
_dio.options.baseUrl,
|
||||
baseUrl,
|
||||
)));
|
||||
final _result = await _dio.fetch<Map<String, dynamic>>(_options);
|
||||
late CreatedDiet _value;
|
||||
try {
|
||||
@@ -107,16 +135,22 @@ class _CreateDietService implements CreateDietService {
|
||||
final _headers = <String, dynamic>{};
|
||||
final _data = <String, dynamic>{};
|
||||
_data.addAll(model);
|
||||
final _options = _setStreamType<void>(
|
||||
Options(method: 'POST', headers: _headers, extra: _extra)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/diets/create/${id}/daily_schedule',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(baseUrl: _combineBaseUrls(_dio.options.baseUrl, baseUrl)),
|
||||
);
|
||||
final _options = _setStreamType<void>(Options(
|
||||
method: 'POST',
|
||||
headers: _headers,
|
||||
extra: _extra,
|
||||
)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/diets/create/${id}/daily_schedule',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(
|
||||
baseUrl: _combineBaseUrls(
|
||||
_dio.options.baseUrl,
|
||||
baseUrl,
|
||||
)));
|
||||
await _dio.fetch<void>(_options);
|
||||
}
|
||||
|
||||
@@ -133,7 +167,10 @@ class _CreateDietService implements CreateDietService {
|
||||
return requestOptions;
|
||||
}
|
||||
|
||||
String _combineBaseUrls(String dioBaseUrl, String? baseUrl) {
|
||||
String _combineBaseUrls(
|
||||
String dioBaseUrl,
|
||||
String? baseUrl,
|
||||
) {
|
||||
if (baseUrl == null || baseUrl.trim().isEmpty) {
|
||||
return dioBaseUrl;
|
||||
}
|
||||
|
||||
@@ -9,7 +9,11 @@ part of 'create_plan_service.dart';
|
||||
// ignore_for_file: unnecessary_brace_in_string_interps,no_leading_underscores_for_local_identifiers,unused_element,unnecessary_string_interpolations
|
||||
|
||||
class _CreatePlanService implements CreatePlanService {
|
||||
_CreatePlanService(this._dio, {this.baseUrl, this.errorLogger});
|
||||
_CreatePlanService(
|
||||
this._dio, {
|
||||
this.baseUrl,
|
||||
this.errorLogger,
|
||||
});
|
||||
|
||||
final Dio _dio;
|
||||
|
||||
@@ -24,21 +28,23 @@ class _CreatePlanService implements CreatePlanService {
|
||||
final _headers = <String, dynamic>{};
|
||||
final _data = <String, dynamic>{};
|
||||
_data.addAll(model);
|
||||
final _options = _setStreamType<void>(
|
||||
Options(
|
||||
method: 'POST',
|
||||
headers: _headers,
|
||||
extra: _extra,
|
||||
contentType: 'multipart/form-data',
|
||||
)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/plans/create',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(baseUrl: _combineBaseUrls(_dio.options.baseUrl, baseUrl)),
|
||||
);
|
||||
final _options = _setStreamType<void>(Options(
|
||||
method: 'POST',
|
||||
headers: _headers,
|
||||
extra: _extra,
|
||||
contentType: 'multipart/form-data',
|
||||
)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/plans/create',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(
|
||||
baseUrl: _combineBaseUrls(
|
||||
_dio.options.baseUrl,
|
||||
baseUrl,
|
||||
)));
|
||||
await _dio.fetch<void>(_options);
|
||||
}
|
||||
|
||||
@@ -52,16 +58,22 @@ class _CreatePlanService implements CreatePlanService {
|
||||
final _headers = <String, dynamic>{};
|
||||
final _data = <String, dynamic>{};
|
||||
_data.addAll(model);
|
||||
final _options = _setStreamType<void>(
|
||||
Options(method: 'POST', headers: _headers, extra: _extra)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/plans/create/${slug}/packet_option',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(baseUrl: _combineBaseUrls(_dio.options.baseUrl, baseUrl)),
|
||||
);
|
||||
final _options = _setStreamType<void>(Options(
|
||||
method: 'POST',
|
||||
headers: _headers,
|
||||
extra: _extra,
|
||||
)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/plans/create/${slug}/packet_option',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(
|
||||
baseUrl: _combineBaseUrls(
|
||||
_dio.options.baseUrl,
|
||||
baseUrl,
|
||||
)));
|
||||
await _dio.fetch<void>(_options);
|
||||
}
|
||||
|
||||
@@ -75,16 +87,22 @@ class _CreatePlanService implements CreatePlanService {
|
||||
final _headers = <String, dynamic>{};
|
||||
final _data = <String, dynamic>{};
|
||||
_data.addAll(model);
|
||||
final _options = _setStreamType<void>(
|
||||
Options(method: 'POST', headers: _headers, extra: _extra)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/plans/create/${slug}/packet_options',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(baseUrl: _combineBaseUrls(_dio.options.baseUrl, baseUrl)),
|
||||
);
|
||||
final _options = _setStreamType<void>(Options(
|
||||
method: 'POST',
|
||||
headers: _headers,
|
||||
extra: _extra,
|
||||
)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/plans/create/${slug}/packet_options',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(
|
||||
baseUrl: _combineBaseUrls(
|
||||
_dio.options.baseUrl,
|
||||
baseUrl,
|
||||
)));
|
||||
await _dio.fetch<void>(_options);
|
||||
}
|
||||
|
||||
@@ -101,7 +119,10 @@ class _CreatePlanService implements CreatePlanService {
|
||||
return requestOptions;
|
||||
}
|
||||
|
||||
String _combineBaseUrls(String dioBaseUrl, String? baseUrl) {
|
||||
String _combineBaseUrls(
|
||||
String dioBaseUrl,
|
||||
String? baseUrl,
|
||||
) {
|
||||
if (baseUrl == null || baseUrl.trim().isEmpty) {
|
||||
return dioBaseUrl;
|
||||
}
|
||||
|
||||
156
lib/features/dev_tools/presentation/dev_tools_screen.dart
Normal file
156
lib/features/dev_tools/presentation/dev_tools_screen.dart
Normal file
@@ -0,0 +1,156 @@
|
||||
import 'package:eatvio_app/core/const.dart';
|
||||
import 'package:eatvio_app/core/utils/toasts.dart';
|
||||
import 'package:eatvio_app/core/widgets/custom_outlined_button.dart';
|
||||
import 'package:eatvio_app/core/widgets/custom_text_form_field.dart';
|
||||
import 'package:eatvio_app/features/dev_tools/test_cases.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class DevToolsScreen extends StatelessWidget {
|
||||
const DevToolsScreen({super.key});
|
||||
static const name = 'devToolsScreen';
|
||||
static const path = '/dev-tools-screen';
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return const DevToolsScreenContent();
|
||||
}
|
||||
}
|
||||
|
||||
class DevToolsScreenContent extends StatefulWidget {
|
||||
const DevToolsScreenContent({super.key});
|
||||
|
||||
@override
|
||||
State<DevToolsScreenContent> createState() => _DevToolsScreenContentState();
|
||||
}
|
||||
|
||||
class _DevToolsScreenContentState extends State<DevToolsScreenContent> {
|
||||
String baseUrlForTest = '';
|
||||
final List<TestCases> testCases = [Test850task()];
|
||||
final controller = TextEditingController();
|
||||
late final List<TestState> testsStates;
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
setState(() {
|
||||
this.baseUrlForTest = baseUrl;
|
||||
});
|
||||
testsStates = List.generate(testCases.length, (index) => TestState.notRun);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(),
|
||||
body: SingleChildScrollView(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 10),
|
||||
child: Column(
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: Row(
|
||||
children: [
|
||||
Text('BaseUrl: ${baseUrlForTest}'),
|
||||
],
|
||||
),
|
||||
),
|
||||
Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: CustomTextFormField(
|
||||
controller: controller,
|
||||
hintText: 'type new base url',
|
||||
),
|
||||
),
|
||||
IconButton(
|
||||
onPressed: () {
|
||||
setState(() {
|
||||
baseUrlForTest = controller.text;
|
||||
controller.clear();
|
||||
});
|
||||
},
|
||||
icon: const Icon(Icons.done),
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(
|
||||
height: 10,
|
||||
),
|
||||
if (baseUrlForTest != 'https://eatvio.ru')
|
||||
ListView.builder(
|
||||
shrinkWrap: true,
|
||||
itemCount: testCases.length,
|
||||
itemBuilder: (context, index) => Row(
|
||||
children: [
|
||||
Text('${index + 1}. ${testCases[index].name}'),
|
||||
SizedBox(
|
||||
width: 50,
|
||||
),
|
||||
Expanded(
|
||||
child: CustomOutlinedButton(
|
||||
text: 'run',
|
||||
height: 20,
|
||||
width: 60,
|
||||
onPressed: () async {
|
||||
if (testsStates[index] == TestState.loading) return;
|
||||
|
||||
setState(() {
|
||||
testsStates[index] = TestState.loading;
|
||||
});
|
||||
final result = await testCases[index].run(baseUrl: baseUrlForTest);
|
||||
if (result) {
|
||||
setState(() {
|
||||
testsStates[index] = TestState.success;
|
||||
});
|
||||
showSuccessToast('${testCases[index].name} passed');
|
||||
} else {
|
||||
setState(() {
|
||||
testsStates[index] = TestState.fail;
|
||||
});
|
||||
showErrorToast('${testCases[index].name} failed');
|
||||
}
|
||||
},
|
||||
buttonStyle: ButtonStyle(),
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
width: 30,
|
||||
),
|
||||
switch (testsStates[index]) {
|
||||
TestState.success => Expanded(
|
||||
child: Container(
|
||||
height: 20,
|
||||
color: Colors.green,
|
||||
),
|
||||
),
|
||||
TestState.fail => Expanded(
|
||||
child: Container(
|
||||
height: 20,
|
||||
color: Colors.red,
|
||||
),
|
||||
),
|
||||
TestState.notRun => Expanded(
|
||||
child: Container(
|
||||
height: 20,
|
||||
color: Colors.grey,
|
||||
),
|
||||
),
|
||||
TestState.loading => Expanded(
|
||||
child: Container(
|
||||
height: 20,
|
||||
child: SizedBox(height: 20, width: 20, child: Center(child: CircularProgressIndicator())),
|
||||
),
|
||||
),
|
||||
},
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
enum TestState { success, fail, notRun, loading }
|
||||
115
lib/features/dev_tools/test_cases.dart
Normal file
115
lib/features/dev_tools/test_cases.dart
Normal file
@@ -0,0 +1,115 @@
|
||||
import 'dart:async';
|
||||
import 'dart:developer';
|
||||
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:eatvio_app/core/locator_service.dart';
|
||||
import 'package:eatvio_app/core/utils/date_time_utils.dart';
|
||||
import 'package:eatvio_app/features/diets/services/diet_service.dart';
|
||||
import 'package:eatvio_app/features/feed/services/feed_service.dart';
|
||||
import 'package:eatvio_app/features/profile/services/profile_service.dart';
|
||||
|
||||
sealed class TestCases {
|
||||
String get name => throw UnimplementedError();
|
||||
|
||||
Future<bool> run({required String baseUrl}) async => throw UnimplementedError();
|
||||
}
|
||||
|
||||
class Test850task implements TestCases {
|
||||
@override
|
||||
String get name => 'task #850';
|
||||
|
||||
@override
|
||||
Future<bool> run({required String baseUrl}) async {
|
||||
try {
|
||||
// get all of needed services
|
||||
final dio = sl<Dio>();
|
||||
final feedService = FeedService(dio, baseUrl: baseUrl);
|
||||
final profileService = ProfileService(dio, baseUrl: baseUrl);
|
||||
final dietsService = DietService(dio, baseUrl: baseUrl);
|
||||
|
||||
// get all of needed data
|
||||
final dietsPaginationModel = await feedService.getDiets(page: 1);
|
||||
final chosenDietsPaginationModel = await profileService.getChosenDiets();
|
||||
final lastChosenDiet = chosenDietsPaginationModel.diets.firstOrNull;
|
||||
final today = DateTime.now();
|
||||
final yesterday = today.subtract(const Duration(days: 1));
|
||||
final tomorrow = today.add(const Duration(days: 1));
|
||||
|
||||
// run test case
|
||||
for (final diet in dietsPaginationModel.data) {
|
||||
if (!diet.author.authorIsMe) {
|
||||
if (lastChosenDiet?.state == 'started' || lastChosenDiet?.state == 'inited') {
|
||||
try {
|
||||
await dietsService.cancelDiet(id: lastChosenDiet?.dietId ?? 0);
|
||||
} catch (e) {
|
||||
log('unexpected error7: $e');
|
||||
return false;
|
||||
}
|
||||
await Future.delayed(Duration(seconds: 3));
|
||||
}
|
||||
try {
|
||||
await dietsService.startDiet(
|
||||
id: diet.id,
|
||||
body: {
|
||||
'date': yesterday.format('yyyy-MM-dd'),
|
||||
},
|
||||
);
|
||||
|
||||
return false;
|
||||
} catch (e) {
|
||||
log('expect ot have error: $e');
|
||||
}
|
||||
|
||||
// test start diet with correct date
|
||||
try {
|
||||
await dietsService.startDiet(
|
||||
id: diet.id,
|
||||
body: {
|
||||
'date': today.format('yyyy-MM-dd'),
|
||||
},
|
||||
);
|
||||
} catch (e) {
|
||||
log('unexpected error2: $e');
|
||||
return false;
|
||||
}
|
||||
|
||||
// test cancelation of diet
|
||||
try {
|
||||
await dietsService.cancelDiet(id: diet.id);
|
||||
} catch (e) {
|
||||
log('unexpected error3: $e');
|
||||
return false;
|
||||
}
|
||||
|
||||
await Future.delayed(Duration(seconds: 3));
|
||||
|
||||
// test start diet with correct date
|
||||
try {
|
||||
await dietsService.startDiet(
|
||||
id: diet.id,
|
||||
body: {
|
||||
'date': tomorrow.format('yyyy-MM-dd'),
|
||||
},
|
||||
);
|
||||
} catch (e) {
|
||||
log('unexpected error4: $e');
|
||||
return false;
|
||||
}
|
||||
|
||||
// test cancelation of diet
|
||||
try {
|
||||
await dietsService.cancelDiet(id: diet.id);
|
||||
} catch (e) {
|
||||
log('unexpected error5: $e');
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
} catch (e) {
|
||||
log('unexpected error6: $e');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,5 @@
|
||||
import 'dart:developer';
|
||||
|
||||
import 'package:eatvio_app/core/widgets/loader.dart';
|
||||
import 'package:eatvio_app/features/diary/presentation/bloc/diary_cubit.dart';
|
||||
import 'package:eatvio_app/features/diary/presentation/bloc/diary_state.dart';
|
||||
@@ -22,6 +24,9 @@ class _DiaryScreenState extends State<DiaryScreen> {
|
||||
create: (BuildContext context) => sl<DiaryCubit>()..fetchDiary(true),
|
||||
child: BlocBuilder<DiaryCubit, DiaryState>(
|
||||
builder: (BuildContext context, DiaryState state) {
|
||||
if (state is DiaryStateLoaded) {
|
||||
log(state.diary.id.toString());
|
||||
}
|
||||
return Scaffold(
|
||||
backgroundColor: Colors.grey.shade200,
|
||||
appBar: AppBar(
|
||||
|
||||
@@ -9,7 +9,11 @@ part of 'diary_service.dart';
|
||||
// ignore_for_file: unnecessary_brace_in_string_interps,no_leading_underscores_for_local_identifiers,unused_element,unnecessary_string_interpolations
|
||||
|
||||
class _DiaryService implements DiaryService {
|
||||
_DiaryService(this._dio, {this.baseUrl, this.errorLogger});
|
||||
_DiaryService(
|
||||
this._dio, {
|
||||
this.baseUrl,
|
||||
this.errorLogger,
|
||||
});
|
||||
|
||||
final Dio _dio;
|
||||
|
||||
@@ -18,30 +22,33 @@ class _DiaryService implements DiaryService {
|
||||
final ParseErrorLogger? errorLogger;
|
||||
|
||||
@override
|
||||
Future<List<DiaryDayModel>> getDiaryIndexByDate({
|
||||
required String date,
|
||||
}) async {
|
||||
Future<List<DiaryDayModel>> getDiaryIndexByDate(
|
||||
{required String date}) async {
|
||||
final _extra = <String, dynamic>{};
|
||||
final queryParameters = <String, dynamic>{};
|
||||
final _headers = <String, dynamic>{};
|
||||
const Map<String, dynamic>? _data = null;
|
||||
final _options = _setStreamType<List<DiaryDayModel>>(
|
||||
Options(method: 'GET', headers: _headers, extra: _extra)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/diary/index/${date}',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(baseUrl: _combineBaseUrls(_dio.options.baseUrl, baseUrl)),
|
||||
);
|
||||
final _options = _setStreamType<List<DiaryDayModel>>(Options(
|
||||
method: 'GET',
|
||||
headers: _headers,
|
||||
extra: _extra,
|
||||
)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/diary/index/${date}',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(
|
||||
baseUrl: _combineBaseUrls(
|
||||
_dio.options.baseUrl,
|
||||
baseUrl,
|
||||
)));
|
||||
final _result = await _dio.fetch<List<dynamic>>(_options);
|
||||
late List<DiaryDayModel> _value;
|
||||
try {
|
||||
_value = _result.data!
|
||||
.map(
|
||||
(dynamic i) => DiaryDayModel.fromJson(i as Map<String, dynamic>),
|
||||
)
|
||||
.map((dynamic i) => DiaryDayModel.fromJson(i as Map<String, dynamic>))
|
||||
.toList();
|
||||
} on Object catch (e, s) {
|
||||
errorLogger?.logError(e, s, _options);
|
||||
@@ -56,16 +63,22 @@ class _DiaryService implements DiaryService {
|
||||
final queryParameters = <String, dynamic>{};
|
||||
final _headers = <String, dynamic>{};
|
||||
const Map<String, dynamic>? _data = null;
|
||||
final _options = _setStreamType<DiaryDayWrapperModel>(
|
||||
Options(method: 'GET', headers: _headers, extra: _extra)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/diary/${diary}/show',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(baseUrl: _combineBaseUrls(_dio.options.baseUrl, baseUrl)),
|
||||
);
|
||||
final _options = _setStreamType<DiaryDayWrapperModel>(Options(
|
||||
method: 'GET',
|
||||
headers: _headers,
|
||||
extra: _extra,
|
||||
)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/diary/${diary}/show',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(
|
||||
baseUrl: _combineBaseUrls(
|
||||
_dio.options.baseUrl,
|
||||
baseUrl,
|
||||
)));
|
||||
final _result = await _dio.fetch<Map<String, dynamic>>(_options);
|
||||
late DiaryDayWrapperModel _value;
|
||||
try {
|
||||
@@ -83,16 +96,22 @@ class _DiaryService implements DiaryService {
|
||||
final queryParameters = <String, dynamic>{};
|
||||
final _headers = <String, dynamic>{};
|
||||
const Map<String, dynamic>? _data = null;
|
||||
final _options = _setStreamType<NutritionDataModel>(
|
||||
Options(method: 'GET', headers: _headers, extra: _extra)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/diary/${diary}/dailyNutritionData',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(baseUrl: _combineBaseUrls(_dio.options.baseUrl, baseUrl)),
|
||||
);
|
||||
final _options = _setStreamType<NutritionDataModel>(Options(
|
||||
method: 'GET',
|
||||
headers: _headers,
|
||||
extra: _extra,
|
||||
)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/diary/${diary}/dailyNutritionData',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(
|
||||
baseUrl: _combineBaseUrls(
|
||||
_dio.options.baseUrl,
|
||||
baseUrl,
|
||||
)));
|
||||
final _result = await _dio.fetch<Map<String, dynamic>>(_options);
|
||||
late NutritionDataModel _value;
|
||||
try {
|
||||
@@ -114,30 +133,30 @@ class _DiaryService implements DiaryService {
|
||||
final queryParameters = <String, dynamic>{};
|
||||
final _headers = <String, dynamic>{};
|
||||
final _data = FormData();
|
||||
_data.files.add(
|
||||
MapEntry(
|
||||
'photo',
|
||||
MultipartFile.fromFileSync(
|
||||
photo.path,
|
||||
filename: photo.path.split(Platform.pathSeparator).last,
|
||||
),
|
||||
_data.files.add(MapEntry(
|
||||
'photo',
|
||||
MultipartFile.fromFileSync(
|
||||
photo.path,
|
||||
filename: photo.path.split(Platform.pathSeparator).last,
|
||||
),
|
||||
);
|
||||
final _options = _setStreamType<void>(
|
||||
Options(
|
||||
method: 'POST',
|
||||
headers: _headers,
|
||||
extra: _extra,
|
||||
contentType: 'multipart/form-data',
|
||||
)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/diary/${diary}/meals/${typeNo}/photo/upload',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(baseUrl: _combineBaseUrls(_dio.options.baseUrl, baseUrl)),
|
||||
);
|
||||
));
|
||||
final _options = _setStreamType<void>(Options(
|
||||
method: 'POST',
|
||||
headers: _headers,
|
||||
extra: _extra,
|
||||
contentType: 'multipart/form-data',
|
||||
)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/diary/${diary}/meals/${typeNo}/photo/upload',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(
|
||||
baseUrl: _combineBaseUrls(
|
||||
_dio.options.baseUrl,
|
||||
baseUrl,
|
||||
)));
|
||||
await _dio.fetch<void>(_options);
|
||||
}
|
||||
|
||||
@@ -151,16 +170,22 @@ class _DiaryService implements DiaryService {
|
||||
final queryParameters = <String, dynamic>{};
|
||||
final _headers = <String, dynamic>{};
|
||||
const Map<String, dynamic>? _data = null;
|
||||
final _options = _setStreamType<void>(
|
||||
Options(method: 'DELETE', headers: _headers, extra: _extra)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/diary/${diaryId}/meals/${typeNo}/photo/${userAttachment}/delete',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(baseUrl: _combineBaseUrls(_dio.options.baseUrl, baseUrl)),
|
||||
);
|
||||
final _options = _setStreamType<void>(Options(
|
||||
method: 'DELETE',
|
||||
headers: _headers,
|
||||
extra: _extra,
|
||||
)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/diary/${diaryId}/meals/${typeNo}/photo/${userAttachment}/delete',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(
|
||||
baseUrl: _combineBaseUrls(
|
||||
_dio.options.baseUrl,
|
||||
baseUrl,
|
||||
)));
|
||||
await _dio.fetch<void>(_options);
|
||||
}
|
||||
|
||||
@@ -178,27 +203,40 @@ class _DiaryService implements DiaryService {
|
||||
queryParameters.removeWhere((k, v) => v == null);
|
||||
final _headers = <String, dynamic>{};
|
||||
final _data = FormData();
|
||||
_data.fields.add(MapEntry('product_name', productName));
|
||||
_data.fields.add(MapEntry('portion', portion));
|
||||
_data.fields.add(MapEntry('quantity', quantity.toString()));
|
||||
_data.fields.add(MapEntry(
|
||||
'product_name',
|
||||
productName,
|
||||
));
|
||||
_data.fields.add(MapEntry(
|
||||
'portion',
|
||||
portion,
|
||||
));
|
||||
_data.fields.add(MapEntry(
|
||||
'quantity',
|
||||
quantity.toString(),
|
||||
));
|
||||
if (productNutritionalValueId != null) {
|
||||
_data.fields.add(
|
||||
MapEntry(
|
||||
'product_nutritional_value_id',
|
||||
productNutritionalValueId.toString(),
|
||||
),
|
||||
);
|
||||
_data.fields.add(MapEntry(
|
||||
'product_nutritional_value_id',
|
||||
productNutritionalValueId.toString(),
|
||||
));
|
||||
}
|
||||
final _options = _setStreamType<void>(
|
||||
Options(method: 'POST', headers: _headers, extra: _extra)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/diary/${diary}/meals/${typeNo}/portion/create',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(baseUrl: _combineBaseUrls(_dio.options.baseUrl, baseUrl)),
|
||||
);
|
||||
final _options = _setStreamType<void>(Options(
|
||||
method: 'POST',
|
||||
headers: _headers,
|
||||
extra: _extra,
|
||||
)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/diary/${diary}/meals/${typeNo}/portion/create',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(
|
||||
baseUrl: _combineBaseUrls(
|
||||
_dio.options.baseUrl,
|
||||
baseUrl,
|
||||
)));
|
||||
await _dio.fetch<void>(_options);
|
||||
}
|
||||
|
||||
@@ -214,16 +252,22 @@ class _DiaryService implements DiaryService {
|
||||
final _headers = <String, dynamic>{};
|
||||
final _data = <String, dynamic>{};
|
||||
_data.addAll(productInMeal);
|
||||
final _options = _setStreamType<void>(
|
||||
Options(method: 'PUT', headers: _headers, extra: _extra)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/diary/${diary}/meals/${typeNo}/portions/${portionModel}/update',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(baseUrl: _combineBaseUrls(_dio.options.baseUrl, baseUrl)),
|
||||
);
|
||||
final _options = _setStreamType<void>(Options(
|
||||
method: 'PUT',
|
||||
headers: _headers,
|
||||
extra: _extra,
|
||||
)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/diary/${diary}/meals/${typeNo}/portions/${portionModel}/update',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(
|
||||
baseUrl: _combineBaseUrls(
|
||||
_dio.options.baseUrl,
|
||||
baseUrl,
|
||||
)));
|
||||
await _dio.fetch<void>(_options);
|
||||
}
|
||||
|
||||
@@ -237,16 +281,22 @@ class _DiaryService implements DiaryService {
|
||||
final queryParameters = <String, dynamic>{};
|
||||
final _headers = <String, dynamic>{};
|
||||
const Map<String, dynamic>? _data = null;
|
||||
final _options = _setStreamType<void>(
|
||||
Options(method: 'POST', headers: _headers, extra: _extra)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/diary/${diary}/meals/${typeNo}/${portionModel}/mark_eaten',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(baseUrl: _combineBaseUrls(_dio.options.baseUrl, baseUrl)),
|
||||
);
|
||||
final _options = _setStreamType<void>(Options(
|
||||
method: 'POST',
|
||||
headers: _headers,
|
||||
extra: _extra,
|
||||
)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/diary/${diary}/meals/${typeNo}/${portionModel}/mark_eaten',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(
|
||||
baseUrl: _combineBaseUrls(
|
||||
_dio.options.baseUrl,
|
||||
baseUrl,
|
||||
)));
|
||||
await _dio.fetch<void>(_options);
|
||||
}
|
||||
|
||||
@@ -260,16 +310,22 @@ class _DiaryService implements DiaryService {
|
||||
final queryParameters = <String, dynamic>{};
|
||||
final _headers = <String, dynamic>{};
|
||||
const Map<String, dynamic>? _data = null;
|
||||
final _options = _setStreamType<void>(
|
||||
Options(method: 'POST', headers: _headers, extra: _extra)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/diary/${diary}/meals/${typeNo}/${portionModel}/unmark_eaten',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(baseUrl: _combineBaseUrls(_dio.options.baseUrl, baseUrl)),
|
||||
);
|
||||
final _options = _setStreamType<void>(Options(
|
||||
method: 'POST',
|
||||
headers: _headers,
|
||||
extra: _extra,
|
||||
)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/diary/${diary}/meals/${typeNo}/${portionModel}/unmark_eaten',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(
|
||||
baseUrl: _combineBaseUrls(
|
||||
_dio.options.baseUrl,
|
||||
baseUrl,
|
||||
)));
|
||||
await _dio.fetch<void>(_options);
|
||||
}
|
||||
|
||||
@@ -283,16 +339,22 @@ class _DiaryService implements DiaryService {
|
||||
final queryParameters = <String, dynamic>{};
|
||||
final _headers = <String, dynamic>{};
|
||||
const Map<String, dynamic>? _data = null;
|
||||
final _options = _setStreamType<void>(
|
||||
Options(method: 'POST', headers: _headers, extra: _extra)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/diary/${diary}/meals/${typeNo}/portions/${portionModel}/restore',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(baseUrl: _combineBaseUrls(_dio.options.baseUrl, baseUrl)),
|
||||
);
|
||||
final _options = _setStreamType<void>(Options(
|
||||
method: 'POST',
|
||||
headers: _headers,
|
||||
extra: _extra,
|
||||
)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/diary/${diary}/meals/${typeNo}/portions/${portionModel}/restore',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(
|
||||
baseUrl: _combineBaseUrls(
|
||||
_dio.options.baseUrl,
|
||||
baseUrl,
|
||||
)));
|
||||
await _dio.fetch<void>(_options);
|
||||
}
|
||||
|
||||
@@ -306,16 +368,22 @@ class _DiaryService implements DiaryService {
|
||||
final queryParameters = <String, dynamic>{};
|
||||
final _headers = <String, dynamic>{};
|
||||
const Map<String, dynamic>? _data = null;
|
||||
final _options = _setStreamType<void>(
|
||||
Options(method: 'DELETE', headers: _headers, extra: _extra)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/diary/${diary}/meals/${typeNo}/portions/${portionModel}/delete',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(baseUrl: _combineBaseUrls(_dio.options.baseUrl, baseUrl)),
|
||||
);
|
||||
final _options = _setStreamType<void>(Options(
|
||||
method: 'DELETE',
|
||||
headers: _headers,
|
||||
extra: _extra,
|
||||
)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/diary/${diary}/meals/${typeNo}/portions/${portionModel}/delete',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(
|
||||
baseUrl: _combineBaseUrls(
|
||||
_dio.options.baseUrl,
|
||||
baseUrl,
|
||||
)));
|
||||
await _dio.fetch<void>(_options);
|
||||
}
|
||||
|
||||
@@ -328,16 +396,22 @@ class _DiaryService implements DiaryService {
|
||||
final queryParameters = <String, dynamic>{};
|
||||
final _headers = <String, dynamic>{};
|
||||
final _data = finishDiaryDayModel;
|
||||
final _options = _setStreamType<void>(
|
||||
Options(method: 'POST', headers: _headers, extra: _extra)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/diary/${diary}/finishDay',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(baseUrl: _combineBaseUrls(_dio.options.baseUrl, baseUrl)),
|
||||
);
|
||||
final _options = _setStreamType<void>(Options(
|
||||
method: 'POST',
|
||||
headers: _headers,
|
||||
extra: _extra,
|
||||
)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/diary/${diary}/finishDay',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(
|
||||
baseUrl: _combineBaseUrls(
|
||||
_dio.options.baseUrl,
|
||||
baseUrl,
|
||||
)));
|
||||
await _dio.fetch<void>(_options);
|
||||
}
|
||||
|
||||
@@ -351,16 +425,22 @@ class _DiaryService implements DiaryService {
|
||||
final queryParameters = <String, dynamic>{};
|
||||
final _headers = <String, dynamic>{};
|
||||
final _data = {'satiety': satiety};
|
||||
final _options = _setStreamType<void>(
|
||||
Options(method: 'POST', headers: _headers, extra: _extra)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/diary/${diary}/meals/${typeNo}/satiety/fill',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(baseUrl: _combineBaseUrls(_dio.options.baseUrl, baseUrl)),
|
||||
);
|
||||
final _options = _setStreamType<void>(Options(
|
||||
method: 'POST',
|
||||
headers: _headers,
|
||||
extra: _extra,
|
||||
)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/diary/${diary}/meals/${typeNo}/satiety/fill',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(
|
||||
baseUrl: _combineBaseUrls(
|
||||
_dio.options.baseUrl,
|
||||
baseUrl,
|
||||
)));
|
||||
await _dio.fetch<void>(_options);
|
||||
}
|
||||
|
||||
@@ -374,38 +454,49 @@ class _DiaryService implements DiaryService {
|
||||
final queryParameters = <String, dynamic>{};
|
||||
final _headers = <String, dynamic>{};
|
||||
final _data = {'time': time};
|
||||
final _options = _setStreamType<void>(
|
||||
Options(method: 'POST', headers: _headers, extra: _extra)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/diary/${diary}/meals/${typeNo}/time/fill',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(baseUrl: _combineBaseUrls(_dio.options.baseUrl, baseUrl)),
|
||||
);
|
||||
final _options = _setStreamType<void>(Options(
|
||||
method: 'POST',
|
||||
headers: _headers,
|
||||
extra: _extra,
|
||||
)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/diary/${diary}/meals/${typeNo}/time/fill',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(
|
||||
baseUrl: _combineBaseUrls(
|
||||
_dio.options.baseUrl,
|
||||
baseUrl,
|
||||
)));
|
||||
await _dio.fetch<void>(_options);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<GlossaryModerationModel> sendProductToModeration({
|
||||
required Map<String, dynamic> data,
|
||||
}) async {
|
||||
Future<GlossaryModerationModel> sendProductToModeration(
|
||||
{required Map<String, dynamic> data}) async {
|
||||
final _extra = <String, dynamic>{};
|
||||
final queryParameters = <String, dynamic>{};
|
||||
final _headers = <String, dynamic>{};
|
||||
final _data = <String, dynamic>{};
|
||||
_data.addAll(data);
|
||||
final _options = _setStreamType<GlossaryModerationModel>(
|
||||
Options(method: 'POST', headers: _headers, extra: _extra)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/diary/product_nutritional_values/sendToModeration',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(baseUrl: _combineBaseUrls(_dio.options.baseUrl, baseUrl)),
|
||||
);
|
||||
final _options = _setStreamType<GlossaryModerationModel>(Options(
|
||||
method: 'POST',
|
||||
headers: _headers,
|
||||
extra: _extra,
|
||||
)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/diary/product_nutritional_values/sendToModeration',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(
|
||||
baseUrl: _combineBaseUrls(
|
||||
_dio.options.baseUrl,
|
||||
baseUrl,
|
||||
)));
|
||||
final _result = await _dio.fetch<Map<String, dynamic>>(_options);
|
||||
late GlossaryModerationModel _value;
|
||||
try {
|
||||
@@ -430,7 +521,10 @@ class _DiaryService implements DiaryService {
|
||||
return requestOptions;
|
||||
}
|
||||
|
||||
String _combineBaseUrls(String dioBaseUrl, String? baseUrl) {
|
||||
String _combineBaseUrls(
|
||||
String dioBaseUrl,
|
||||
String? baseUrl,
|
||||
) {
|
||||
if (baseUrl == null || baseUrl.trim().isEmpty) {
|
||||
return dioBaseUrl;
|
||||
}
|
||||
|
||||
@@ -28,4 +28,15 @@ abstract class DietService {
|
||||
Future<Diet> getDiet({
|
||||
@Path() required int id,
|
||||
});
|
||||
|
||||
@POST('/api/diets/{id}/start')
|
||||
Future<void> startDiet({
|
||||
@Path() required int id,
|
||||
@Body() required Map<String, dynamic> body,
|
||||
});
|
||||
|
||||
@POST('/api/diets/{id}/cancel')
|
||||
Future<void> cancelDiet({
|
||||
@Path() required int id,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -9,7 +9,11 @@ part of 'diet_service.dart';
|
||||
// ignore_for_file: unnecessary_brace_in_string_interps,no_leading_underscores_for_local_identifiers,unused_element,unnecessary_string_interpolations
|
||||
|
||||
class _DietService implements DietService {
|
||||
_DietService(this._dio, {this.baseUrl, this.errorLogger});
|
||||
_DietService(
|
||||
this._dio, {
|
||||
this.baseUrl,
|
||||
this.errorLogger,
|
||||
});
|
||||
|
||||
final Dio _dio;
|
||||
|
||||
@@ -23,16 +27,22 @@ class _DietService implements DietService {
|
||||
final queryParameters = <String, dynamic>{};
|
||||
final _headers = <String, dynamic>{};
|
||||
const Map<String, dynamic>? _data = null;
|
||||
final _options = _setStreamType<DietLikesModel>(
|
||||
Options(method: 'POST', headers: _headers, extra: _extra)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/diets/${id}/like',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(baseUrl: _combineBaseUrls(_dio.options.baseUrl, baseUrl)),
|
||||
);
|
||||
final _options = _setStreamType<DietLikesModel>(Options(
|
||||
method: 'POST',
|
||||
headers: _headers,
|
||||
extra: _extra,
|
||||
)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/diets/${id}/like',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(
|
||||
baseUrl: _combineBaseUrls(
|
||||
_dio.options.baseUrl,
|
||||
baseUrl,
|
||||
)));
|
||||
final _result = await _dio.fetch<Map<String, dynamic>>(_options);
|
||||
late DietLikesModel _value;
|
||||
try {
|
||||
@@ -50,16 +60,22 @@ class _DietService implements DietService {
|
||||
final queryParameters = <String, dynamic>{};
|
||||
final _headers = <String, dynamic>{};
|
||||
const Map<String, dynamic>? _data = null;
|
||||
final _options = _setStreamType<Diet>(
|
||||
Options(method: 'POST', headers: _headers, extra: _extra)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/diets/${id}/add_to_favorite',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(baseUrl: _combineBaseUrls(_dio.options.baseUrl, baseUrl)),
|
||||
);
|
||||
final _options = _setStreamType<Diet>(Options(
|
||||
method: 'POST',
|
||||
headers: _headers,
|
||||
extra: _extra,
|
||||
)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/diets/${id}/add_to_favorite',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(
|
||||
baseUrl: _combineBaseUrls(
|
||||
_dio.options.baseUrl,
|
||||
baseUrl,
|
||||
)));
|
||||
final _result = await _dio.fetch<Map<String, dynamic>>(_options);
|
||||
late Diet _value;
|
||||
try {
|
||||
@@ -77,16 +93,22 @@ class _DietService implements DietService {
|
||||
final queryParameters = <String, dynamic>{};
|
||||
final _headers = <String, dynamic>{};
|
||||
const Map<String, dynamic>? _data = null;
|
||||
final _options = _setStreamType<Diet>(
|
||||
Options(method: 'POST', headers: _headers, extra: _extra)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/diets/${id}/remove_from_favorite',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(baseUrl: _combineBaseUrls(_dio.options.baseUrl, baseUrl)),
|
||||
);
|
||||
final _options = _setStreamType<Diet>(Options(
|
||||
method: 'POST',
|
||||
headers: _headers,
|
||||
extra: _extra,
|
||||
)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/diets/${id}/remove_from_favorite',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(
|
||||
baseUrl: _combineBaseUrls(
|
||||
_dio.options.baseUrl,
|
||||
baseUrl,
|
||||
)));
|
||||
final _result = await _dio.fetch<Map<String, dynamic>>(_options);
|
||||
late Diet _value;
|
||||
try {
|
||||
@@ -104,16 +126,22 @@ class _DietService implements DietService {
|
||||
final queryParameters = <String, dynamic>{};
|
||||
final _headers = <String, dynamic>{};
|
||||
const Map<String, dynamic>? _data = null;
|
||||
final _options = _setStreamType<Diet>(
|
||||
Options(method: 'GET', headers: _headers, extra: _extra)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/diets/show/${id}',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(baseUrl: _combineBaseUrls(_dio.options.baseUrl, baseUrl)),
|
||||
);
|
||||
final _options = _setStreamType<Diet>(Options(
|
||||
method: 'GET',
|
||||
headers: _headers,
|
||||
extra: _extra,
|
||||
)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/diets/show/${id}',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(
|
||||
baseUrl: _combineBaseUrls(
|
||||
_dio.options.baseUrl,
|
||||
baseUrl,
|
||||
)));
|
||||
final _result = await _dio.fetch<Map<String, dynamic>>(_options);
|
||||
late Diet _value;
|
||||
try {
|
||||
@@ -125,6 +153,60 @@ class _DietService implements DietService {
|
||||
return _value;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> startDiet({
|
||||
required int id,
|
||||
required Map<String, dynamic> body,
|
||||
}) async {
|
||||
final _extra = <String, dynamic>{};
|
||||
final queryParameters = <String, dynamic>{};
|
||||
final _headers = <String, dynamic>{};
|
||||
final _data = <String, dynamic>{};
|
||||
_data.addAll(body);
|
||||
final _options = _setStreamType<void>(Options(
|
||||
method: 'POST',
|
||||
headers: _headers,
|
||||
extra: _extra,
|
||||
)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/diets/${id}/start',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(
|
||||
baseUrl: _combineBaseUrls(
|
||||
_dio.options.baseUrl,
|
||||
baseUrl,
|
||||
)));
|
||||
await _dio.fetch<void>(_options);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> cancelDiet({required int id}) async {
|
||||
final _extra = <String, dynamic>{};
|
||||
final queryParameters = <String, dynamic>{};
|
||||
final _headers = <String, dynamic>{};
|
||||
const Map<String, dynamic>? _data = null;
|
||||
final _options = _setStreamType<void>(Options(
|
||||
method: 'POST',
|
||||
headers: _headers,
|
||||
extra: _extra,
|
||||
)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/diets/${id}/cancel',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(
|
||||
baseUrl: _combineBaseUrls(
|
||||
_dio.options.baseUrl,
|
||||
baseUrl,
|
||||
)));
|
||||
await _dio.fetch<void>(_options);
|
||||
}
|
||||
|
||||
RequestOptions _setStreamType<T>(RequestOptions requestOptions) {
|
||||
if (T != dynamic &&
|
||||
!(requestOptions.responseType == ResponseType.bytes ||
|
||||
@@ -138,7 +220,10 @@ class _DietService implements DietService {
|
||||
return requestOptions;
|
||||
}
|
||||
|
||||
String _combineBaseUrls(String dioBaseUrl, String? baseUrl) {
|
||||
String _combineBaseUrls(
|
||||
String dioBaseUrl,
|
||||
String? baseUrl,
|
||||
) {
|
||||
if (baseUrl == null || baseUrl.trim().isEmpty) {
|
||||
return dioBaseUrl;
|
||||
}
|
||||
|
||||
@@ -39,7 +39,7 @@ class PlanModel with _$PlanModel {
|
||||
@JsonKey(name: "is_favorite") required bool isFavorite,
|
||||
@JsonKey(name: "min_price_of_options") required double minPriceOfOptions,
|
||||
@JsonKey(name: "max_price_of_options") required double maxPriceOfOptions,
|
||||
@Default(false) bool wasLikedByMe,
|
||||
@JsonKey(name: "was_liked_by_me") required bool wasLikedByMe,
|
||||
}) = _PlanModel;
|
||||
|
||||
factory PlanModel.fromJson(Map<String, dynamic> json) => _$PlanModelFromJson(json);
|
||||
|
||||
@@ -298,6 +298,7 @@ mixin _$PlanModel {
|
||||
double get minPriceOfOptions => throw _privateConstructorUsedError;
|
||||
@JsonKey(name: "max_price_of_options")
|
||||
double get maxPriceOfOptions => throw _privateConstructorUsedError;
|
||||
@JsonKey(name: "was_liked_by_me")
|
||||
bool get wasLikedByMe => throw _privateConstructorUsedError;
|
||||
|
||||
/// Serializes this PlanModel to a JSON map.
|
||||
@@ -335,7 +336,7 @@ abstract class $PlanModelCopyWith<$Res> {
|
||||
@JsonKey(name: "is_favorite") bool isFavorite,
|
||||
@JsonKey(name: "min_price_of_options") double minPriceOfOptions,
|
||||
@JsonKey(name: "max_price_of_options") double maxPriceOfOptions,
|
||||
bool wasLikedByMe});
|
||||
@JsonKey(name: "was_liked_by_me") bool wasLikedByMe});
|
||||
|
||||
$PlanTypeCopyWith<$Res> get type;
|
||||
$PacketOptionsCopyWith<$Res>? get packet1Options;
|
||||
@@ -555,7 +556,7 @@ abstract class _$$PlanModelImplCopyWith<$Res>
|
||||
@JsonKey(name: "is_favorite") bool isFavorite,
|
||||
@JsonKey(name: "min_price_of_options") double minPriceOfOptions,
|
||||
@JsonKey(name: "max_price_of_options") double maxPriceOfOptions,
|
||||
bool wasLikedByMe});
|
||||
@JsonKey(name: "was_liked_by_me") bool wasLikedByMe});
|
||||
|
||||
@override
|
||||
$PlanTypeCopyWith<$Res> get type;
|
||||
@@ -711,7 +712,7 @@ class _$PlanModelImpl implements _PlanModel {
|
||||
@JsonKey(name: "is_favorite") required this.isFavorite,
|
||||
@JsonKey(name: "min_price_of_options") required this.minPriceOfOptions,
|
||||
@JsonKey(name: "max_price_of_options") required this.maxPriceOfOptions,
|
||||
this.wasLikedByMe = false});
|
||||
@JsonKey(name: "was_liked_by_me") required this.wasLikedByMe});
|
||||
|
||||
factory _$PlanModelImpl.fromJson(Map<String, dynamic> json) =>
|
||||
_$$PlanModelImplFromJson(json);
|
||||
@@ -774,7 +775,7 @@ class _$PlanModelImpl implements _PlanModel {
|
||||
@JsonKey(name: "max_price_of_options")
|
||||
final double maxPriceOfOptions;
|
||||
@override
|
||||
@JsonKey()
|
||||
@JsonKey(name: "was_liked_by_me")
|
||||
final bool wasLikedByMe;
|
||||
|
||||
@override
|
||||
@@ -865,29 +866,30 @@ class _$PlanModelImpl implements _PlanModel {
|
||||
|
||||
abstract class _PlanModel implements PlanModel {
|
||||
const factory _PlanModel(
|
||||
{@JsonKey(name: "id") required final int id,
|
||||
@JsonKey(name: "slug") required final String slug,
|
||||
@JsonKey(name: "name") required final String name,
|
||||
@JsonKey(name: "image") required final String image,
|
||||
@JsonKey(name: "duration") required final int duration,
|
||||
@JsonKey(name: "state") required final String state,
|
||||
@JsonKey(name: "type", fromJson: planTypeFromJson)
|
||||
required final PlanType type,
|
||||
@JsonKey(name: "details") required final String details,
|
||||
@JsonKey(name: "packets_count") required final int packetsCount,
|
||||
@JsonKey(name: "packet1_options") final PacketOptions? packet1Options,
|
||||
@JsonKey(name: "packet2_options") final PacketOptions? packet2Options,
|
||||
@JsonKey(name: "packet3_options") final PacketOptions? packet3Options,
|
||||
@JsonKey(name: "author") required final Author author,
|
||||
@JsonKey(name: "total_likes") required final int totalLikes,
|
||||
@JsonKey(name: "total_views") required final int totalViews,
|
||||
@JsonKey(name: "total_comments") required final int totalComments,
|
||||
@JsonKey(name: "is_favorite") required final bool isFavorite,
|
||||
@JsonKey(name: "min_price_of_options")
|
||||
required final double minPriceOfOptions,
|
||||
@JsonKey(name: "max_price_of_options")
|
||||
required final double maxPriceOfOptions,
|
||||
final bool wasLikedByMe}) = _$PlanModelImpl;
|
||||
{@JsonKey(name: "id") required final int id,
|
||||
@JsonKey(name: "slug") required final String slug,
|
||||
@JsonKey(name: "name") required final String name,
|
||||
@JsonKey(name: "image") required final String image,
|
||||
@JsonKey(name: "duration") required final int duration,
|
||||
@JsonKey(name: "state") required final String state,
|
||||
@JsonKey(name: "type", fromJson: planTypeFromJson)
|
||||
required final PlanType type,
|
||||
@JsonKey(name: "details") required final String details,
|
||||
@JsonKey(name: "packets_count") required final int packetsCount,
|
||||
@JsonKey(name: "packet1_options") final PacketOptions? packet1Options,
|
||||
@JsonKey(name: "packet2_options") final PacketOptions? packet2Options,
|
||||
@JsonKey(name: "packet3_options") final PacketOptions? packet3Options,
|
||||
@JsonKey(name: "author") required final Author author,
|
||||
@JsonKey(name: "total_likes") required final int totalLikes,
|
||||
@JsonKey(name: "total_views") required final int totalViews,
|
||||
@JsonKey(name: "total_comments") required final int totalComments,
|
||||
@JsonKey(name: "is_favorite") required final bool isFavorite,
|
||||
@JsonKey(name: "min_price_of_options")
|
||||
required final double minPriceOfOptions,
|
||||
@JsonKey(name: "max_price_of_options")
|
||||
required final double maxPriceOfOptions,
|
||||
@JsonKey(name: "was_liked_by_me") required final bool wasLikedByMe}) =
|
||||
_$PlanModelImpl;
|
||||
|
||||
factory _PlanModel.fromJson(Map<String, dynamic> json) =
|
||||
_$PlanModelImpl.fromJson;
|
||||
@@ -950,6 +952,7 @@ abstract class _PlanModel implements PlanModel {
|
||||
@JsonKey(name: "max_price_of_options")
|
||||
double get maxPriceOfOptions;
|
||||
@override
|
||||
@JsonKey(name: "was_liked_by_me")
|
||||
bool get wasLikedByMe;
|
||||
|
||||
/// Create a copy of PlanModel
|
||||
|
||||
@@ -54,7 +54,7 @@ _$PlanModelImpl _$$PlanModelImplFromJson(Map<String, dynamic> json) =>
|
||||
isFavorite: json['is_favorite'] as bool,
|
||||
minPriceOfOptions: (json['min_price_of_options'] as num).toDouble(),
|
||||
maxPriceOfOptions: (json['max_price_of_options'] as num).toDouble(),
|
||||
wasLikedByMe: json['wasLikedByMe'] as bool? ?? false,
|
||||
wasLikedByMe: json['was_liked_by_me'] as bool,
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$$PlanModelImplToJson(_$PlanModelImpl instance) =>
|
||||
@@ -78,7 +78,7 @@ Map<String, dynamic> _$$PlanModelImplToJson(_$PlanModelImpl instance) =>
|
||||
'is_favorite': instance.isFavorite,
|
||||
'min_price_of_options': instance.minPriceOfOptions,
|
||||
'max_price_of_options': instance.maxPriceOfOptions,
|
||||
'wasLikedByMe': instance.wasLikedByMe,
|
||||
'was_liked_by_me': instance.wasLikedByMe,
|
||||
};
|
||||
|
||||
_$PacketOptionsImpl _$$PacketOptionsImplFromJson(Map<String, dynamic> json) =>
|
||||
|
||||
@@ -9,7 +9,7 @@ import 'package:eatvio_app/features/feed/presentation/bloc/diets_cubit/diets_sta
|
||||
import 'package:eatvio_app/features/feed/repositories/feed_repository.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
|
||||
class DietsCubit extends Cubit<DietsState>{
|
||||
class DietsCubit extends Cubit<DietsState> {
|
||||
final FeedRepository feedRepository;
|
||||
final DietRepository dietsRepository;
|
||||
int currentPage = 1;
|
||||
@@ -52,7 +52,6 @@ class DietsCubit extends Cubit<DietsState>{
|
||||
super.close();
|
||||
}
|
||||
|
||||
|
||||
void changeTypeFilter(int index) {
|
||||
emit(state.copyWith(filterState: state.filterState.copyWith(typeIndex: index), errorMessage: null));
|
||||
EasyDebounce.debounce(
|
||||
@@ -64,7 +63,6 @@ class DietsCubit extends Cubit<DietsState>{
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
void changeSortingType(int index) {
|
||||
emit(state.copyWith(filterState: state.filterState.copyWith(sortingIndex: index), errorMessage: null));
|
||||
EasyDebounce.debounce(
|
||||
@@ -76,7 +74,6 @@ class DietsCubit extends Cubit<DietsState>{
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
void changeDurationFilter(int index) {
|
||||
emit(state.copyWith(filterState: state.filterState.copyWith(durationIndex: index), errorMessage: null));
|
||||
EasyDebounce.debounce(
|
||||
@@ -153,6 +150,7 @@ class DietsCubit extends Cubit<DietsState>{
|
||||
|
||||
Future<void> likeDiet(int id, int index) async {
|
||||
final currentDiets = state.dietsList;
|
||||
// if (currentDiets.isEmpty) return;
|
||||
final dietsForModification = [...currentDiets];
|
||||
final currentDiet = currentDiets[index];
|
||||
if (currentDiet.wasLikedByMe) {
|
||||
|
||||
@@ -284,4 +284,58 @@ class PlansCubit extends Cubit<PlansState> {
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> likePlan(String slug, int index) async {
|
||||
final currentPlans = state.plans;
|
||||
final plansForModification = [...currentPlans];
|
||||
final currentPlan = currentPlans[index];
|
||||
if (currentPlan.wasLikedByMe) {
|
||||
plansForModification[index] = currentPlan.copyWith(
|
||||
totalLikes: currentPlan.totalLikes - 1,
|
||||
wasLikedByMe: false,
|
||||
);
|
||||
emit(
|
||||
state.copyWith(
|
||||
plans: [
|
||||
...plansForModification,
|
||||
],
|
||||
isLoading: isLoading,
|
||||
errorMessage: null,
|
||||
),
|
||||
);
|
||||
} else {
|
||||
plansForModification[index] = currentPlan.copyWith(
|
||||
totalLikes: currentPlan.totalLikes + 1,
|
||||
wasLikedByMe: true,
|
||||
);
|
||||
emit(
|
||||
state.copyWith(
|
||||
plans: [
|
||||
...plansForModification,
|
||||
],
|
||||
isLoading: isLoading,
|
||||
errorMessage: null,
|
||||
),
|
||||
);
|
||||
}
|
||||
EasyDebounce.debounce(
|
||||
'like_plan',
|
||||
Duration(milliseconds: 200),
|
||||
() async {
|
||||
try {
|
||||
await planRepository.likePlan(slug);
|
||||
} catch (e) {
|
||||
log(e.toString());
|
||||
emit(
|
||||
state.copyWith(
|
||||
plans: [
|
||||
...currentPlans,
|
||||
],
|
||||
isLoading: isLoading,
|
||||
),
|
||||
);
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,13 +28,16 @@ class RecipesCubit extends Cubit<RecipesState> {
|
||||
query: query,
|
||||
);
|
||||
final recipesTags = (await recipeRepository.getRecipesTags());
|
||||
emit(RecipesState.loaded(
|
||||
recipesList: recipesList,
|
||||
recipesTags: recipesTags,
|
||||
selectedTags: _selectedTags,
|
||||
selectedTagsCounter: _selectedTags.length,
|
||||
isLoading: isLoading,
|
||||
),);
|
||||
emit(
|
||||
RecipesState.loaded(
|
||||
recipesList: recipesList,
|
||||
recipesTags: recipesTags,
|
||||
selectedTags: _selectedTags,
|
||||
selectedTagsCounter: _selectedTags.length,
|
||||
isLoading: isLoading,
|
||||
),
|
||||
);
|
||||
lastPage = currentPage;
|
||||
} catch (e) {
|
||||
emit(RecipesState.error(errorMessage: e.toString()));
|
||||
}
|
||||
@@ -55,14 +58,17 @@ class RecipesCubit extends Cubit<RecipesState> {
|
||||
query: _query,
|
||||
);
|
||||
isLoading = false;
|
||||
emit((state as RecipesStateLoaded).copyWith(
|
||||
recipesList: [
|
||||
...(state as RecipesStateLoaded).recipesList,
|
||||
...recipesList,
|
||||
],
|
||||
isLoading: isLoading,
|
||||
),);
|
||||
emit(
|
||||
(state as RecipesStateLoaded).copyWith(
|
||||
recipesList: [
|
||||
...(state as RecipesStateLoaded).recipesList,
|
||||
...recipesList,
|
||||
],
|
||||
isLoading: isLoading,
|
||||
),
|
||||
);
|
||||
}
|
||||
lastPage = currentPage;
|
||||
} catch (e) {
|
||||
emit(RecipesState.error(errorMessage: e.toString()));
|
||||
}
|
||||
@@ -71,9 +77,11 @@ class RecipesCubit extends Cubit<RecipesState> {
|
||||
|
||||
updateTags(RecipeTag tag) {
|
||||
_selectedTags.contains(tag.id) ? _selectedTags.remove(tag.id) : _selectedTags.add(tag.id);
|
||||
emit((state as RecipesStateLoaded).copyWith(
|
||||
selectedTags: _selectedTags,
|
||||
selectedTagsCounter: _selectedTags.length,
|
||||
),);
|
||||
emit(
|
||||
(state as RecipesStateLoaded).copyWith(
|
||||
selectedTags: _selectedTags,
|
||||
selectedTagsCounter: _selectedTags.length,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,53 +2,74 @@ import 'package:easy_debounce/easy_debounce.dart';
|
||||
import 'package:eatvio_app/core/widgets/add_item_button.dart';
|
||||
import 'package:eatvio_app/core/widgets/custom_search_bar.dart';
|
||||
import 'package:eatvio_app/features/create_diet/presentation/create_diet_screen.dart';
|
||||
import 'package:eatvio_app/core/widgets/loader.dart';
|
||||
import 'package:eatvio_app/features/create_plan/presentation/create_plan_screen.dart';
|
||||
import 'package:eatvio_app/features/feed/presentation/bloc/consultants_cubit/consultants_cubit.dart';
|
||||
import 'package:eatvio_app/features/feed/presentation/bloc/consultants_cubit/consultants_state.dart';
|
||||
import 'package:eatvio_app/features/feed/presentation/bloc/diets_cubit/diets_cubit.dart';
|
||||
import 'package:eatvio_app/features/feed/presentation/bloc/diets_cubit/diets_state.dart';
|
||||
import 'package:eatvio_app/features/feed/presentation/bloc/feed_cubit/feed_cubit.dart';
|
||||
import 'package:eatvio_app/features/feed/presentation/bloc/feed_cubit/feed_state.dart';
|
||||
import 'package:eatvio_app/features/feed/presentation/bloc/profile_cubit/profile_cubit.dart';
|
||||
import 'package:eatvio_app/features/feed/presentation/bloc/profile_cubit/profile_state.dart';
|
||||
import 'package:eatvio_app/features/feed/presentation/bloc/recipes_cubit/recipes_cubit.dart';
|
||||
import 'package:eatvio_app/features/feed/presentation/bloc/recipes_cubit/recipes_state.dart';
|
||||
import 'package:eatvio_app/features/feed/presentation/widgets/blog_post_widget.dart';
|
||||
import 'package:eatvio_app/features/feed/presentation/widgets/blog_posts.dart';
|
||||
import 'package:eatvio_app/features/feed/presentation/widgets/choice_chip_widget.dart';
|
||||
import 'package:eatvio_app/features/feed/presentation/widgets/consultant_widget.dart';
|
||||
import 'package:eatvio_app/features/feed/presentation/widgets/diet_filter_bottom_sheet.dart';
|
||||
import 'package:eatvio_app/features/feed/presentation/widgets/diets_widget.dart';
|
||||
import 'package:eatvio_app/features/feed/presentation/widgets/filter_badge.dart';
|
||||
import 'package:eatvio_app/features/feed/presentation/widgets/plan_widget.dart';
|
||||
import 'package:eatvio_app/features/feed/presentation/widgets/plans_filter_bottom_sheet.dart';
|
||||
import 'package:eatvio_app/features/feed/presentation/widgets/recipes_widget.dart';
|
||||
import 'package:eatvio_app/features/feed/presentation/widgets/consultants.dart';
|
||||
import 'package:eatvio_app/features/feed/presentation/widgets/diets.dart';
|
||||
import 'package:eatvio_app/features/feed/presentation/widgets/plans.dart';
|
||||
import 'package:eatvio_app/features/feed/presentation/widgets/tags_modal_widget.dart';
|
||||
import 'package:eatvio_app/features/feed/presentation/bloc/plans_cubit/plans_cubit.dart';
|
||||
import 'package:eatvio_app/features/feed/presentation/bloc/plans_cubit/plans_state.dart';
|
||||
import 'package:eatvio_app/core/locator_service.dart';
|
||||
import 'package:eatvio_app/core/theme/theme_helper.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
|
||||
import '../widgets/recipes.dart';
|
||||
|
||||
final bucket = PageStorageBucket();
|
||||
|
||||
class FeedScreen extends StatefulWidget {
|
||||
class FeedScreen extends StatelessWidget {
|
||||
const FeedScreen({super.key});
|
||||
|
||||
@override
|
||||
State<FeedScreen> createState() => _FeedScreenState();
|
||||
Widget build(BuildContext context) {
|
||||
return MultiBlocProvider(
|
||||
providers: [
|
||||
BlocProvider<RecipesCubit>(
|
||||
create: (context) => sl<RecipesCubit>()..loadRecipesList(),
|
||||
),
|
||||
BlocProvider<FeedProfileCubit>(
|
||||
create: (context) => sl<FeedProfileCubit>()..getProfile(),
|
||||
),
|
||||
BlocProvider<FeedCubit>(
|
||||
create: (context) => sl<FeedCubit>()..loadFeedBlogPostList(),
|
||||
),
|
||||
BlocProvider<DietsCubit>(
|
||||
create: (context) => sl<DietsCubit>()..loadDiets(),
|
||||
),
|
||||
BlocProvider<PlansCubit>(
|
||||
create: (context) => sl<PlansCubit>()..loadPlans(),
|
||||
),
|
||||
BlocProvider<ConsultantsCubit>(
|
||||
create: (context) => sl<ConsultantsCubit>()..getConsultants(),
|
||||
),
|
||||
],
|
||||
child: const FeedScreenContent(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _FeedScreenState extends State<FeedScreen> {
|
||||
final FeedCubit feedCubit = sl<FeedCubit>();
|
||||
final RecipesCubit recipesCubit = sl<RecipesCubit>()..loadRecipesList();
|
||||
final DietsCubit dietsCubit = sl<DietsCubit>()..loadDiets();
|
||||
final PlansCubit plansCubit = sl<PlansCubit>()..loadPlans();
|
||||
final ConsultantsCubit consultantsCubit = sl<ConsultantsCubit>()..getConsultants();
|
||||
class FeedScreenContent extends StatefulWidget {
|
||||
const FeedScreenContent({super.key});
|
||||
|
||||
final searchController = TextEditingController();
|
||||
@override
|
||||
State<FeedScreenContent> createState() => _FeedScreenContentState();
|
||||
}
|
||||
|
||||
class _FeedScreenContentState extends State<FeedScreenContent> {
|
||||
final postsController = TextEditingController();
|
||||
final recipesController = TextEditingController();
|
||||
final dietsController = TextEditingController();
|
||||
final plansController = TextEditingController();
|
||||
final consultantsController = TextEditingController();
|
||||
final List<String> chipsLabelList = ['Все', 'Рецепты', 'Диеты', 'Планы питания', 'Консультанты'];
|
||||
int _selectedChipIndex = 0;
|
||||
final blogPostsScrollController = ScrollController();
|
||||
@@ -59,7 +80,6 @@ class _FeedScreenState extends State<FeedScreen> {
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
feedCubit.loadFeedBlogPostList();
|
||||
blogPostsScrollController.addListener(_onScrollBlogPosts);
|
||||
recipesScrollController.addListener(_onScrollRecipes);
|
||||
dietsScrollController.addListener(_onScrollDiets);
|
||||
@@ -70,25 +90,25 @@ class _FeedScreenState extends State<FeedScreen> {
|
||||
|
||||
_onScrollBlogPosts() {
|
||||
if (blogPostsScrollController.offset >= blogPostsScrollController.position.maxScrollExtent && !blogPostsScrollController.position.outOfRange) {
|
||||
feedCubit.loadNextPage();
|
||||
context.read<FeedCubit>().loadNextPage();
|
||||
}
|
||||
}
|
||||
|
||||
_onScrollRecipes() {
|
||||
if (recipesScrollController.offset >= recipesScrollController.position.maxScrollExtent && !recipesScrollController.position.outOfRange) {
|
||||
recipesCubit.loadNextPage();
|
||||
context.read<RecipesCubit>().loadNextPage();
|
||||
}
|
||||
}
|
||||
|
||||
_onScrollDiets() {
|
||||
if (dietsScrollController.offset >= dietsScrollController.position.maxScrollExtent && !dietsScrollController.position.outOfRange) {
|
||||
dietsCubit.loadNextPage();
|
||||
context.read<DietsCubit>().loadNextPage();
|
||||
}
|
||||
}
|
||||
|
||||
_onScrollPlans() {
|
||||
if (plansScrollController.offset >= plansScrollController.position.maxScrollExtent && !plansScrollController.position.outOfRange) {
|
||||
plansCubit.loadNextPage();
|
||||
context.read<PlansCubit>().loadNextPage();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -107,402 +127,148 @@ class _FeedScreenState extends State<FeedScreen> {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return MultiBlocProvider(
|
||||
providers: [
|
||||
BlocProvider<FeedProfileCubit>(
|
||||
create: (context) => sl<FeedProfileCubit>()..getProfile(),
|
||||
),
|
||||
BlocProvider<RecipesCubit>(
|
||||
create: (context) => sl<RecipesCubit>()..loadRecipesList(),
|
||||
),
|
||||
BlocProvider<DietsCubit>(
|
||||
create: (context) => sl<DietsCubit>()..loadDiets(),
|
||||
),
|
||||
BlocProvider<PlansCubit>(
|
||||
create: (context) => sl<PlansCubit>()..loadPlans(),
|
||||
),
|
||||
BlocProvider<ConsultantsCubit>(
|
||||
create: (context) => sl<ConsultantsCubit>()..getConsultants(),
|
||||
),
|
||||
],
|
||||
child: Scaffold(
|
||||
floatingActionButton: _selectedChipIndex == 1
|
||||
? FloatingActionButton.small(
|
||||
heroTag: 'recipesTagsFilter',
|
||||
backgroundColor: appTheme.blueA400,
|
||||
shape: CircleBorder(),
|
||||
child: Icon(
|
||||
Icons.filter_list_rounded,
|
||||
color: Colors.white,
|
||||
),
|
||||
onPressed: () async {
|
||||
await showModalBottomSheet(
|
||||
useRootNavigator: true,
|
||||
context: context,
|
||||
builder: (context) => TagsModalWidget(
|
||||
recipesCubit: recipesCubit,
|
||||
),
|
||||
);
|
||||
recipesCubit.loadRecipesList();
|
||||
},
|
||||
)
|
||||
: null,
|
||||
appBar: AppBar(
|
||||
backgroundColor: Colors.white,
|
||||
toolbarHeight: 0,
|
||||
),
|
||||
backgroundColor: Colors.grey.shade200,
|
||||
body: NestedScrollView(
|
||||
controller: switch (_selectedChipIndex) {
|
||||
0 => blogPostsScrollController,
|
||||
1 => recipesScrollController,
|
||||
2 => dietsScrollController,
|
||||
3 => plansScrollController,
|
||||
4 => consultantsScrollController,
|
||||
_ => blogPostsScrollController
|
||||
},
|
||||
headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
|
||||
return [
|
||||
BlocBuilder<FeedProfileCubit, ProfileState>(
|
||||
builder: (context, state) {
|
||||
return SliverAppBar(
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.vertical(bottom: Radius.circular(12)),
|
||||
),
|
||||
backgroundColor: Colors.white,
|
||||
foregroundColor: Colors.white,
|
||||
automaticallyImplyLeading: false,
|
||||
stretchTriggerOffset: 1,
|
||||
floating: true,
|
||||
snap: true,
|
||||
scrolledUnderElevation: 0,
|
||||
bottom: _chipGroup(),
|
||||
title: Row(
|
||||
children: [
|
||||
CustomSearchBar(
|
||||
searchController: searchController,
|
||||
onChanged: (query) {
|
||||
if (query.length > 2) {
|
||||
EasyDebounce.debounce(
|
||||
'searchFeed',
|
||||
Duration(milliseconds: 500),
|
||||
() {
|
||||
switch (_selectedChipIndex) {
|
||||
case 0:
|
||||
feedCubit.loadFeedBlogPostList(query: query);
|
||||
break;
|
||||
case 1:
|
||||
recipesCubit.loadRecipesList(query: query);
|
||||
break;
|
||||
case 2:
|
||||
dietsCubit.loadDiets(query: query);
|
||||
break;
|
||||
case 3:
|
||||
plansCubit.loadPlans(query: query);
|
||||
break;
|
||||
case 4:
|
||||
consultantsCubit.getConsultants();
|
||||
break;
|
||||
}
|
||||
},
|
||||
);
|
||||
} else {
|
||||
EasyDebounce.debounce(
|
||||
'searchFeed',
|
||||
Duration(milliseconds: 500),
|
||||
() {
|
||||
switch (_selectedChipIndex) {
|
||||
case 0:
|
||||
feedCubit.loadFeedBlogPostList();
|
||||
break;
|
||||
case 1:
|
||||
recipesCubit.loadRecipesList();
|
||||
break;
|
||||
case 2:
|
||||
dietsCubit.loadDiets();
|
||||
break;
|
||||
case 3:
|
||||
plansCubit.loadPlans();
|
||||
break;
|
||||
case 4:
|
||||
consultantsCubit.getConsultants();
|
||||
break;
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
},
|
||||
),
|
||||
SizedBox(width: 12),
|
||||
switch (_selectedChipIndex) {
|
||||
1 => AddItemButton(
|
||||
onTap: () => GoRouter.of(context).pushNamed('recipeCreateScreen'),
|
||||
),
|
||||
2 => AddItemButton(
|
||||
onTap: state.profile?.role == 'consultant' ? () => GoRouter.of(context).pushNamed(CreateDietScreen.name) : null,
|
||||
),
|
||||
3 => AddItemButton(
|
||||
onTap: state.profile?.role == 'consultant' ? () => GoRouter.of(context).pushNamed(CreatePlanScreen.name) : null,
|
||||
),
|
||||
_ => AddItemButton()
|
||||
},
|
||||
],
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
];
|
||||
},
|
||||
body: switch (_selectedChipIndex) {
|
||||
0 => _buildAllBlogPosts(),
|
||||
1 => _buildAllRecipes(),
|
||||
2 => _buildDiets(),
|
||||
3 => _buildPlans(),
|
||||
4 => _buildConsultants(),
|
||||
_ => Center(child: Text(chipsLabelList[_selectedChipIndex])),
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
_buildAllBlogPosts() {
|
||||
return RefreshIndicator(
|
||||
onRefresh: () => feedCubit.loadFeedBlogPostList(),
|
||||
child: BlocBuilder<FeedCubit, FeedState>(
|
||||
builder: (BuildContext context, FeedState state) {
|
||||
if (state is FeedStateLoaded) {
|
||||
return ListView.separated(
|
||||
padding: EdgeInsets.symmetric(vertical: 8),
|
||||
shrinkWrap: true,
|
||||
physics: BouncingScrollPhysics(),
|
||||
itemBuilder: (context, index) {
|
||||
if (index == state.feedBlogPostList.length) {
|
||||
return const Loader();
|
||||
}
|
||||
return BlogPostWidget(index: index);
|
||||
},
|
||||
separatorBuilder: (context, index) {
|
||||
return SizedBox(height: 8);
|
||||
},
|
||||
itemCount: state.isLoading ? state.feedBlogPostList.length + 1 : state.feedBlogPostList.length,
|
||||
);
|
||||
} else if (state is FeedStateError) {
|
||||
return Scaffold(
|
||||
backgroundColor: Colors.grey.shade200,
|
||||
body: Padding(
|
||||
padding: const EdgeInsets.all(16),
|
||||
child: Center(
|
||||
child: Text(state.errorMessage),
|
||||
),
|
||||
),
|
||||
);
|
||||
} else {
|
||||
return Scaffold(
|
||||
backgroundColor: Colors.grey.shade200,
|
||||
body: const Loader(),
|
||||
);
|
||||
}
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
_buildConsultants() {
|
||||
return RefreshIndicator(
|
||||
onRefresh: () => consultantsCubit.getConsultants(),
|
||||
child: BlocBuilder<ConsultantsCubit, ConsultantsState>(
|
||||
bloc: consultantsCubit,
|
||||
builder: (BuildContext context, ConsultantsState state) {
|
||||
if (state is ConsultantsStateLoaded) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 8),
|
||||
child: Material(
|
||||
return Scaffold(
|
||||
floatingActionButton: _selectedChipIndex == 1
|
||||
? FloatingActionButton.small(
|
||||
heroTag: 'recipesTagsFilter',
|
||||
backgroundColor: appTheme.blueA400,
|
||||
shape: CircleBorder(),
|
||||
child: Icon(
|
||||
Icons.filter_list_rounded,
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16),
|
||||
child: ListView.separated(
|
||||
padding: EdgeInsets.symmetric(vertical: 16),
|
||||
shrinkWrap: true,
|
||||
physics: BouncingScrollPhysics(),
|
||||
itemBuilder: (context, index) {
|
||||
return ConsultantWidget(consultant: state.consultantsList[index]);
|
||||
},
|
||||
separatorBuilder: (context, index) {
|
||||
return SizedBox(height: 12);
|
||||
},
|
||||
itemCount: state.consultantsList.length,
|
||||
),
|
||||
onPressed: () async {
|
||||
final recipesCubit = context.read<RecipesCubit>();
|
||||
await showModalBottomSheet(
|
||||
useRootNavigator: true,
|
||||
context: context,
|
||||
builder: (context) => TagsModalWidget(
|
||||
recipesCubit: recipesCubit,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
} else if (state is ConsultantsStateError) {
|
||||
return Scaffold(
|
||||
backgroundColor: Colors.grey.shade200,
|
||||
body: Padding(
|
||||
padding: const EdgeInsets.all(16),
|
||||
child: Center(
|
||||
child: Text(state.errorMessage),
|
||||
),
|
||||
),
|
||||
);
|
||||
} else {
|
||||
return Scaffold(
|
||||
backgroundColor: Colors.grey.shade200,
|
||||
body: const Loader(),
|
||||
);
|
||||
}
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
_buildAllRecipes() {
|
||||
return RefreshIndicator(
|
||||
onRefresh: () => recipesCubit.loadRecipesList(),
|
||||
child: BlocBuilder<RecipesCubit, RecipesState>(
|
||||
bloc: recipesCubit,
|
||||
builder: (BuildContext context, RecipesState state) {
|
||||
if (state is RecipesStateLoaded) {
|
||||
return ListView.separated(
|
||||
padding: EdgeInsets.symmetric(vertical: 8),
|
||||
shrinkWrap: true,
|
||||
physics: BouncingScrollPhysics(),
|
||||
itemBuilder: (context, index) {
|
||||
return RecipesWidget(recipes: state.recipesList[index]);
|
||||
);
|
||||
recipesCubit.loadRecipesList();
|
||||
},
|
||||
separatorBuilder: (context, index) {
|
||||
return SizedBox(height: 8);
|
||||
)
|
||||
: null,
|
||||
appBar: AppBar(
|
||||
backgroundColor: Colors.white,
|
||||
toolbarHeight: 0,
|
||||
),
|
||||
backgroundColor: Colors.grey.shade200,
|
||||
body: NestedScrollView(
|
||||
controller: switch (_selectedChipIndex) {
|
||||
0 => blogPostsScrollController,
|
||||
1 => recipesScrollController,
|
||||
2 => dietsScrollController,
|
||||
3 => plansScrollController,
|
||||
4 => consultantsScrollController,
|
||||
_ => blogPostsScrollController
|
||||
},
|
||||
headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
|
||||
return [
|
||||
BlocBuilder<FeedProfileCubit, ProfileState>(
|
||||
builder: (context, state) {
|
||||
return SliverAppBar(
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.vertical(bottom: Radius.circular(12)),
|
||||
),
|
||||
backgroundColor: Colors.white,
|
||||
foregroundColor: Colors.white,
|
||||
automaticallyImplyLeading: false,
|
||||
stretchTriggerOffset: 1,
|
||||
floating: true,
|
||||
snap: true,
|
||||
scrolledUnderElevation: 0,
|
||||
bottom: _chipGroup(),
|
||||
title: Row(
|
||||
children: [
|
||||
CustomSearchBar(
|
||||
searchController: switch (_selectedChipIndex) {
|
||||
1 => recipesController,
|
||||
2 => dietsController,
|
||||
3 => plansController,
|
||||
4 => consultantsController,
|
||||
_ => postsController,
|
||||
},
|
||||
onChanged: (query) {
|
||||
if (query.length > 2) {
|
||||
EasyDebounce.debounce(
|
||||
'searchFeed',
|
||||
Duration(milliseconds: 500),
|
||||
() {
|
||||
switch (_selectedChipIndex) {
|
||||
case 0:
|
||||
context.read<FeedCubit>().loadFeedBlogPostList(query: query);
|
||||
break;
|
||||
case 1:
|
||||
context.read<RecipesCubit>().loadRecipesList(query: query);
|
||||
break;
|
||||
case 2:
|
||||
context.read<DietsCubit>().loadDiets(query: query);
|
||||
break;
|
||||
case 3:
|
||||
context.read<PlansCubit>().loadPlans(query: query);
|
||||
break;
|
||||
case 4:
|
||||
context.read<ConsultantsCubit>().getConsultants();
|
||||
break;
|
||||
}
|
||||
},
|
||||
);
|
||||
} else {
|
||||
EasyDebounce.debounce(
|
||||
'searchFeed',
|
||||
Duration(milliseconds: 500),
|
||||
() {
|
||||
switch (_selectedChipIndex) {
|
||||
case 0:
|
||||
context.read<FeedCubit>().loadFeedBlogPostList();
|
||||
break;
|
||||
case 1:
|
||||
context.read<RecipesCubit>().loadRecipesList();
|
||||
break;
|
||||
case 2:
|
||||
context.read<DietsCubit>().loadDiets();
|
||||
break;
|
||||
case 3:
|
||||
context.read<PlansCubit>().loadPlans();
|
||||
break;
|
||||
case 4:
|
||||
context.read<ConsultantsCubit>().getConsultants();
|
||||
break;
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
},
|
||||
),
|
||||
SizedBox(width: 12),
|
||||
switch (_selectedChipIndex) {
|
||||
1 => AddItemButton(
|
||||
onTap: () => GoRouter.of(context).pushNamed('recipeCreateScreen'),
|
||||
),
|
||||
2 => AddItemButton(
|
||||
onTap: state.profile?.role == 'consultant' ? () => GoRouter.of(context).pushNamed(CreateDietScreen.name) : null,
|
||||
),
|
||||
3 => AddItemButton(
|
||||
onTap: state.profile?.role == 'consultant' ? () => GoRouter.of(context).pushNamed(CreatePlanScreen.name) : null,
|
||||
),
|
||||
_ => AddItemButton()
|
||||
},
|
||||
],
|
||||
),
|
||||
);
|
||||
},
|
||||
itemCount: state.recipesList.length,
|
||||
);
|
||||
} else if (state is RecipesStateError) {
|
||||
return Scaffold(
|
||||
backgroundColor: Colors.grey.shade200,
|
||||
body: Padding(
|
||||
padding: const EdgeInsets.all(16),
|
||||
child: Center(
|
||||
child: Text(state.errorMessage),
|
||||
),
|
||||
),
|
||||
);
|
||||
} else {
|
||||
return Scaffold(
|
||||
backgroundColor: Colors.grey.shade200,
|
||||
body: const Loader(),
|
||||
);
|
||||
}
|
||||
),
|
||||
];
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
_buildDiets() {
|
||||
return RefreshIndicator(
|
||||
onRefresh: () => dietsCubit.loadDiets(),
|
||||
child: BlocBuilder<DietsCubit, DietsState>(
|
||||
bloc: dietsCubit,
|
||||
builder: (BuildContext context, DietsState state) {
|
||||
if (state.isLoading) {
|
||||
return Scaffold(
|
||||
backgroundColor: Colors.grey.shade200,
|
||||
body: const Loader(),
|
||||
);
|
||||
} else if (state.errorMessage != null) {
|
||||
return Scaffold(
|
||||
backgroundColor: Colors.grey.shade200,
|
||||
body: Padding(
|
||||
padding: const EdgeInsets.all(16),
|
||||
child: Center(
|
||||
child: Text(state.errorMessage ?? ''),
|
||||
),
|
||||
),
|
||||
);
|
||||
} else {
|
||||
return Stack(
|
||||
children: [
|
||||
SizedBox.expand(),
|
||||
ListView.separated(
|
||||
padding: EdgeInsets.symmetric(vertical: 8),
|
||||
shrinkWrap: true,
|
||||
physics: BouncingScrollPhysics(),
|
||||
itemBuilder: (context, index) {
|
||||
return DietsWidget(diet: state.dietsList[index], index: index);
|
||||
},
|
||||
separatorBuilder: (context, index) {
|
||||
return SizedBox(height: 8);
|
||||
},
|
||||
itemCount: state.dietsList.length,
|
||||
),
|
||||
Positioned(
|
||||
right: 0,
|
||||
bottom: 74,
|
||||
child: FilterBadge(
|
||||
filterBottomSheet: DietFilterBottomSheet(
|
||||
dietsCubit: dietsCubit,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
_buildPlans() {
|
||||
return RefreshIndicator(
|
||||
onRefresh: () => plansCubit.loadPlans(),
|
||||
child: BlocBuilder<PlansCubit, PlansState>(
|
||||
bloc: plansCubit,
|
||||
builder: (BuildContext context, PlansState state) {
|
||||
if (state.isLoading) {
|
||||
return Scaffold(
|
||||
backgroundColor: Colors.grey.shade200,
|
||||
body: const Loader(),
|
||||
);
|
||||
} else if (state.errorMessage != null) {
|
||||
return Scaffold(
|
||||
backgroundColor: Colors.grey.shade200,
|
||||
body: Padding(
|
||||
padding: const EdgeInsets.all(16),
|
||||
child: Center(
|
||||
child: Text(state.errorMessage ?? ''),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
return Stack(
|
||||
children: [
|
||||
SizedBox.expand(),
|
||||
ListView.separated(
|
||||
padding: EdgeInsets.symmetric(vertical: 8),
|
||||
shrinkWrap: true,
|
||||
physics: BouncingScrollPhysics(),
|
||||
itemBuilder: (context, index) {
|
||||
return PlanWidget(
|
||||
plan: state.plans[index],
|
||||
index: index,
|
||||
);
|
||||
},
|
||||
separatorBuilder: (context, index) {
|
||||
return SizedBox(height: 8);
|
||||
},
|
||||
itemCount: state.plans.length,
|
||||
),
|
||||
Positioned(
|
||||
right: 0,
|
||||
bottom: 74,
|
||||
child: FilterBadge(
|
||||
filterBottomSheet: PlansFilterBottomSheet(
|
||||
plansCubit: plansCubit,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
body: switch (_selectedChipIndex) {
|
||||
0 => BlogPosts(),
|
||||
1 => Recipes(),
|
||||
2 => Diets(),
|
||||
3 => Plans(),
|
||||
4 => Consultants(),
|
||||
_ => Center(child: Text(chipsLabelList[_selectedChipIndex])),
|
||||
},
|
||||
),
|
||||
);
|
||||
@@ -525,7 +291,6 @@ class _FeedScreenState extends State<FeedScreen> {
|
||||
onSelected: (bool selected) {
|
||||
setState(() {
|
||||
_selectedChipIndex = 0;
|
||||
searchController.clear();
|
||||
FocusScope.of(context).requestFocus(new FocusNode());
|
||||
});
|
||||
},
|
||||
@@ -538,7 +303,6 @@ class _FeedScreenState extends State<FeedScreen> {
|
||||
onSelected: (bool selected) {
|
||||
setState(() {
|
||||
_selectedChipIndex = 1;
|
||||
searchController.clear();
|
||||
FocusScope.of(context).requestFocus(new FocusNode());
|
||||
});
|
||||
},
|
||||
@@ -551,7 +315,6 @@ class _FeedScreenState extends State<FeedScreen> {
|
||||
onSelected: (bool selected) {
|
||||
setState(() {
|
||||
_selectedChipIndex = 2;
|
||||
searchController.clear();
|
||||
FocusScope.of(context).requestFocus(new FocusNode());
|
||||
});
|
||||
},
|
||||
@@ -564,7 +327,6 @@ class _FeedScreenState extends State<FeedScreen> {
|
||||
onSelected: (bool selected) {
|
||||
setState(() {
|
||||
_selectedChipIndex = 3;
|
||||
searchController.clear();
|
||||
FocusScope.of(context).requestFocus(new FocusNode());
|
||||
});
|
||||
},
|
||||
@@ -577,7 +339,6 @@ class _FeedScreenState extends State<FeedScreen> {
|
||||
onSelected: (bool selected) {
|
||||
setState(() {
|
||||
_selectedChipIndex = 4;
|
||||
searchController.clear();
|
||||
FocusScope.of(context).requestFocus(new FocusNode());
|
||||
});
|
||||
},
|
||||
|
||||
53
lib/features/feed/presentation/widgets/blog_posts.dart
Normal file
53
lib/features/feed/presentation/widgets/blog_posts.dart
Normal file
@@ -0,0 +1,53 @@
|
||||
import 'package:eatvio_app/core/widgets/loader.dart';
|
||||
import 'package:eatvio_app/features/feed/presentation/bloc/feed_cubit/feed_cubit.dart';
|
||||
import 'package:eatvio_app/features/feed/presentation/bloc/feed_cubit/feed_state.dart';
|
||||
import 'package:eatvio_app/features/feed/presentation/widgets/blog_post_widget.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
|
||||
class BlogPosts extends StatelessWidget {
|
||||
const BlogPosts({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return RefreshIndicator(
|
||||
onRefresh: () => context.read<FeedCubit>().loadFeedBlogPostList(),
|
||||
child: BlocBuilder<FeedCubit, FeedState>(
|
||||
builder: (BuildContext context, FeedState state) {
|
||||
if (state is FeedStateLoaded) {
|
||||
return ListView.separated(
|
||||
padding: EdgeInsets.symmetric(vertical: 8),
|
||||
shrinkWrap: true,
|
||||
physics: BouncingScrollPhysics(),
|
||||
itemBuilder: (context, index) {
|
||||
if (index == state.feedBlogPostList.length) {
|
||||
return const Loader();
|
||||
}
|
||||
return BlogPostWidget(index: index);
|
||||
},
|
||||
separatorBuilder: (context, index) {
|
||||
return SizedBox(height: 8);
|
||||
},
|
||||
itemCount: state.isLoading ? state.feedBlogPostList.length + 1 : state.feedBlogPostList.length,
|
||||
);
|
||||
} else if (state is FeedStateError) {
|
||||
return Scaffold(
|
||||
backgroundColor: Colors.grey.shade200,
|
||||
body: Padding(
|
||||
padding: const EdgeInsets.all(16),
|
||||
child: Center(
|
||||
child: Text(state.errorMessage),
|
||||
),
|
||||
),
|
||||
);
|
||||
} else {
|
||||
return Scaffold(
|
||||
backgroundColor: Colors.grey.shade200,
|
||||
body: const Loader(),
|
||||
);
|
||||
}
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
62
lib/features/feed/presentation/widgets/consultants.dart
Normal file
62
lib/features/feed/presentation/widgets/consultants.dart
Normal file
@@ -0,0 +1,62 @@
|
||||
import 'package:eatvio_app/core/widgets/loader.dart';
|
||||
import 'package:eatvio_app/features/feed/presentation/bloc/consultants_cubit/consultants_cubit.dart';
|
||||
import 'package:eatvio_app/features/feed/presentation/bloc/consultants_cubit/consultants_state.dart';
|
||||
import 'package:eatvio_app/features/feed/presentation/widgets/consultant_widget.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
|
||||
class Consultants extends StatelessWidget {
|
||||
const Consultants({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return RefreshIndicator(
|
||||
onRefresh: () => context.read<ConsultantsCubit>().getConsultants(),
|
||||
child: BlocBuilder<ConsultantsCubit, ConsultantsState>(
|
||||
builder: (BuildContext context, ConsultantsState state) {
|
||||
if (state is ConsultantsStateLoaded) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 8),
|
||||
child: Material(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16),
|
||||
child: ListView.separated(
|
||||
padding: EdgeInsets.symmetric(vertical: 16),
|
||||
shrinkWrap: true,
|
||||
physics: BouncingScrollPhysics(),
|
||||
itemBuilder: (context, index) {
|
||||
return ConsultantWidget(consultant: state.consultantsList[index]);
|
||||
},
|
||||
separatorBuilder: (context, index) {
|
||||
return SizedBox(height: 12);
|
||||
},
|
||||
itemCount: state.consultantsList.length,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
} else if (state is ConsultantsStateError) {
|
||||
return Scaffold(
|
||||
backgroundColor: Colors.grey.shade200,
|
||||
body: Padding(
|
||||
padding: const EdgeInsets.all(16),
|
||||
child: Center(
|
||||
child: Text(state.errorMessage),
|
||||
),
|
||||
),
|
||||
);
|
||||
} else {
|
||||
return Scaffold(
|
||||
backgroundColor: Colors.grey.shade200,
|
||||
body: const Loader(),
|
||||
);
|
||||
}
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
66
lib/features/feed/presentation/widgets/diets.dart
Normal file
66
lib/features/feed/presentation/widgets/diets.dart
Normal file
@@ -0,0 +1,66 @@
|
||||
import 'package:eatvio_app/core/widgets/loader.dart';
|
||||
import 'package:eatvio_app/features/feed/presentation/bloc/diets_cubit/diets_cubit.dart';
|
||||
import 'package:eatvio_app/features/feed/presentation/bloc/diets_cubit/diets_state.dart';
|
||||
import 'package:eatvio_app/features/feed/presentation/widgets/diet_filter_bottom_sheet.dart';
|
||||
import 'package:eatvio_app/features/feed/presentation/widgets/diets_widget.dart';
|
||||
import 'package:eatvio_app/features/feed/presentation/widgets/filter_badge.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
|
||||
class Diets extends StatelessWidget {
|
||||
const Diets({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return RefreshIndicator(
|
||||
onRefresh: () => context.read<DietsCubit>().loadDiets(),
|
||||
child: BlocBuilder<DietsCubit, DietsState>(
|
||||
builder: (BuildContext context, DietsState state) {
|
||||
if (state.isLoading) {
|
||||
return Scaffold(
|
||||
backgroundColor: Colors.grey.shade200,
|
||||
body: const Loader(),
|
||||
);
|
||||
} else if (state.errorMessage != null) {
|
||||
return Scaffold(
|
||||
backgroundColor: Colors.grey.shade200,
|
||||
body: Padding(
|
||||
padding: const EdgeInsets.all(16),
|
||||
child: Center(
|
||||
child: Text(state.errorMessage ?? ''),
|
||||
),
|
||||
),
|
||||
);
|
||||
} else {
|
||||
return Stack(
|
||||
children: [
|
||||
SizedBox.expand(),
|
||||
ListView.separated(
|
||||
padding: EdgeInsets.symmetric(vertical: 8),
|
||||
shrinkWrap: true,
|
||||
physics: BouncingScrollPhysics(),
|
||||
itemBuilder: (context, index) {
|
||||
return DietsWidget(diet: state.dietsList[index], index: index);
|
||||
},
|
||||
separatorBuilder: (context, index) {
|
||||
return SizedBox(height: 8);
|
||||
},
|
||||
itemCount: state.dietsList.length,
|
||||
),
|
||||
Positioned(
|
||||
right: 0,
|
||||
bottom: 74,
|
||||
child: FilterBadge(
|
||||
filterBottomSheet: DietFilterBottomSheet(
|
||||
dietsCubit: context.read<DietsCubit>(),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -5,7 +5,6 @@ import 'package:eatvio_app/core/widgets/info_row.dart';
|
||||
import 'package:eatvio_app/core/widgets/feed_icon_button.dart';
|
||||
import 'package:eatvio_app/features/diets/presentation/widgets/info_bouble.dart';
|
||||
import 'package:eatvio_app/features/feed/models/plan_pagination_model.dart';
|
||||
import 'package:eatvio_app/features/feed/presentation/bloc/diets_cubit/diets_cubit.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/feed/presentation/bloc/plans_cubit/plans_cubit.dart';
|
||||
@@ -183,7 +182,7 @@ class _PlanWidgetState extends State<PlanWidget> {
|
||||
iconColor: widget.plan.wasLikedByMe ? appTheme.blueA400 : null,
|
||||
backgroundColor: widget.plan.wasLikedByMe ? appTheme.transparentBlue : null,
|
||||
onTap: () async {
|
||||
await context.read<DietsCubit>().likeDiet(widget.plan.id, widget.index);
|
||||
await context.read<PlansCubit>().likePlan(widget.plan.slug, widget.index);
|
||||
},
|
||||
),
|
||||
SizedBox(
|
||||
|
||||
68
lib/features/feed/presentation/widgets/plans.dart
Normal file
68
lib/features/feed/presentation/widgets/plans.dart
Normal file
@@ -0,0 +1,68 @@
|
||||
import 'package:eatvio_app/core/widgets/loader.dart';
|
||||
import 'package:eatvio_app/features/feed/presentation/bloc/plans_cubit/plans_cubit.dart';
|
||||
import 'package:eatvio_app/features/feed/presentation/bloc/plans_cubit/plans_state.dart';
|
||||
import 'package:eatvio_app/features/feed/presentation/widgets/filter_badge.dart';
|
||||
import 'package:eatvio_app/features/feed/presentation/widgets/plan_widget.dart';
|
||||
import 'package:eatvio_app/features/feed/presentation/widgets/plans_filter_bottom_sheet.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
|
||||
class Plans extends StatelessWidget {
|
||||
const Plans({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return RefreshIndicator(
|
||||
onRefresh: () => context.read<PlansCubit>().loadPlans(),
|
||||
child: BlocBuilder<PlansCubit, PlansState>(
|
||||
builder: (BuildContext context, PlansState state) {
|
||||
if (state.isLoading) {
|
||||
return Scaffold(
|
||||
backgroundColor: Colors.grey.shade200,
|
||||
body: const Loader(),
|
||||
);
|
||||
} else if (state.errorMessage != null) {
|
||||
return Scaffold(
|
||||
backgroundColor: Colors.grey.shade200,
|
||||
body: Padding(
|
||||
padding: const EdgeInsets.all(16),
|
||||
child: Center(
|
||||
child: Text(state.errorMessage ?? ''),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
return Stack(
|
||||
children: [
|
||||
SizedBox.expand(),
|
||||
ListView.separated(
|
||||
padding: EdgeInsets.symmetric(vertical: 8),
|
||||
shrinkWrap: true,
|
||||
physics: BouncingScrollPhysics(),
|
||||
itemBuilder: (context, index) {
|
||||
return PlanWidget(
|
||||
plan: state.plans[index],
|
||||
index: index,
|
||||
);
|
||||
},
|
||||
separatorBuilder: (context, index) {
|
||||
return SizedBox(height: 8);
|
||||
},
|
||||
itemCount: state.plans.length,
|
||||
),
|
||||
Positioned(
|
||||
right: 0,
|
||||
bottom: 74,
|
||||
child: FilterBadge(
|
||||
filterBottomSheet: PlansFilterBottomSheet(
|
||||
plansCubit: context.read<PlansCubit>(),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
50
lib/features/feed/presentation/widgets/recipes.dart
Normal file
50
lib/features/feed/presentation/widgets/recipes.dart
Normal file
@@ -0,0 +1,50 @@
|
||||
import 'package:eatvio_app/core/widgets/loader.dart';
|
||||
import 'package:eatvio_app/features/feed/presentation/bloc/recipes_cubit/recipes_cubit.dart';
|
||||
import 'package:eatvio_app/features/feed/presentation/bloc/recipes_cubit/recipes_state.dart';
|
||||
import 'package:eatvio_app/features/feed/presentation/widgets/recipes_widget.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
|
||||
class Recipes extends StatelessWidget {
|
||||
const Recipes({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return RefreshIndicator(
|
||||
onRefresh: () => context.read<RecipesCubit>().loadRecipesList(),
|
||||
child: BlocBuilder<RecipesCubit, RecipesState>(
|
||||
builder: (BuildContext context, RecipesState state) {
|
||||
if (state is RecipesStateLoaded) {
|
||||
return ListView.separated(
|
||||
padding: EdgeInsets.symmetric(vertical: 8),
|
||||
shrinkWrap: true,
|
||||
physics: BouncingScrollPhysics(),
|
||||
itemBuilder: (context, index) {
|
||||
return RecipesWidget(recipes: state.recipesList[index]);
|
||||
},
|
||||
separatorBuilder: (context, index) {
|
||||
return SizedBox(height: 8);
|
||||
},
|
||||
itemCount: state.recipesList.length,
|
||||
);
|
||||
} else if (state is RecipesStateError) {
|
||||
return Scaffold(
|
||||
backgroundColor: Colors.grey.shade200,
|
||||
body: Padding(
|
||||
padding: const EdgeInsets.all(16),
|
||||
child: Center(
|
||||
child: Text(state.errorMessage),
|
||||
),
|
||||
),
|
||||
);
|
||||
} else {
|
||||
return Scaffold(
|
||||
backgroundColor: Colors.grey.shade200,
|
||||
body: const Loader(),
|
||||
);
|
||||
}
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -9,7 +9,11 @@ part of 'feed_service.dart';
|
||||
// ignore_for_file: unnecessary_brace_in_string_interps,no_leading_underscores_for_local_identifiers,unused_element,unnecessary_string_interpolations
|
||||
|
||||
class _FeedService implements FeedService {
|
||||
_FeedService(this._dio, {this.baseUrl, this.errorLogger});
|
||||
_FeedService(
|
||||
this._dio, {
|
||||
this.baseUrl,
|
||||
this.errorLogger,
|
||||
});
|
||||
|
||||
final Dio _dio;
|
||||
|
||||
@@ -30,16 +34,22 @@ class _FeedService implements FeedService {
|
||||
queryParameters.removeWhere((k, v) => v == null);
|
||||
final _headers = <String, dynamic>{};
|
||||
const Map<String, dynamic>? _data = null;
|
||||
final _options = _setStreamType<FeedBlogPostSettingsModel>(
|
||||
Options(method: 'GET', headers: _headers, extra: _extra)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/blogPosts/index',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(baseUrl: _combineBaseUrls(_dio.options.baseUrl, baseUrl)),
|
||||
);
|
||||
final _options = _setStreamType<FeedBlogPostSettingsModel>(Options(
|
||||
method: 'GET',
|
||||
headers: _headers,
|
||||
extra: _extra,
|
||||
)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/blogPosts/index',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(
|
||||
baseUrl: _combineBaseUrls(
|
||||
_dio.options.baseUrl,
|
||||
baseUrl,
|
||||
)));
|
||||
final _result = await _dio.fetch<Map<String, dynamic>>(_options);
|
||||
late FeedBlogPostSettingsModel _value;
|
||||
try {
|
||||
@@ -66,16 +76,22 @@ class _FeedService implements FeedService {
|
||||
queryParameters.removeWhere((k, v) => v == null);
|
||||
final _headers = <String, dynamic>{};
|
||||
const Map<String, dynamic>? _data = null;
|
||||
final _options = _setStreamType<RecipesPagination>(
|
||||
Options(method: 'GET', headers: _headers, extra: _extra)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/recipes/index',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(baseUrl: _combineBaseUrls(_dio.options.baseUrl, baseUrl)),
|
||||
);
|
||||
final _options = _setStreamType<RecipesPagination>(Options(
|
||||
method: 'GET',
|
||||
headers: _headers,
|
||||
extra: _extra,
|
||||
)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/recipes/index',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(
|
||||
baseUrl: _combineBaseUrls(
|
||||
_dio.options.baseUrl,
|
||||
baseUrl,
|
||||
)));
|
||||
final _result = await _dio.fetch<Map<String, dynamic>>(_options);
|
||||
late RecipesPagination _value;
|
||||
try {
|
||||
@@ -106,16 +122,22 @@ class _FeedService implements FeedService {
|
||||
queryParameters.removeWhere((k, v) => v == null);
|
||||
final _headers = <String, dynamic>{};
|
||||
const Map<String, dynamic>? _data = null;
|
||||
final _options = _setStreamType<DietsPagination>(
|
||||
Options(method: 'GET', headers: _headers, extra: _extra)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/diets/index',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(baseUrl: _combineBaseUrls(_dio.options.baseUrl, baseUrl)),
|
||||
);
|
||||
final _options = _setStreamType<DietsPagination>(Options(
|
||||
method: 'GET',
|
||||
headers: _headers,
|
||||
extra: _extra,
|
||||
)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/diets/index',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(
|
||||
baseUrl: _combineBaseUrls(
|
||||
_dio.options.baseUrl,
|
||||
baseUrl,
|
||||
)));
|
||||
final _result = await _dio.fetch<Map<String, dynamic>>(_options);
|
||||
late DietsPagination _value;
|
||||
try {
|
||||
@@ -148,16 +170,22 @@ class _FeedService implements FeedService {
|
||||
queryParameters.removeWhere((k, v) => v == null);
|
||||
final _headers = <String, dynamic>{};
|
||||
const Map<String, dynamic>? _data = null;
|
||||
final _options = _setStreamType<PlanPaginationModel>(
|
||||
Options(method: 'GET', headers: _headers, extra: _extra)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/plans/index',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(baseUrl: _combineBaseUrls(_dio.options.baseUrl, baseUrl)),
|
||||
);
|
||||
final _options = _setStreamType<PlanPaginationModel>(Options(
|
||||
method: 'GET',
|
||||
headers: _headers,
|
||||
extra: _extra,
|
||||
)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/plans/index',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(
|
||||
baseUrl: _combineBaseUrls(
|
||||
_dio.options.baseUrl,
|
||||
baseUrl,
|
||||
)));
|
||||
final _result = await _dio.fetch<Map<String, dynamic>>(_options);
|
||||
late PlanPaginationModel _value;
|
||||
try {
|
||||
@@ -175,16 +203,22 @@ class _FeedService implements FeedService {
|
||||
final queryParameters = <String, dynamic>{};
|
||||
final _headers = <String, dynamic>{};
|
||||
const Map<String, dynamic>? _data = null;
|
||||
final _options = _setStreamType<CommentModel>(
|
||||
Options(method: 'GET', headers: _headers, extra: _extra)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/blogPosts/${id}/comments/show',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(baseUrl: _combineBaseUrls(_dio.options.baseUrl, baseUrl)),
|
||||
);
|
||||
final _options = _setStreamType<CommentModel>(Options(
|
||||
method: 'GET',
|
||||
headers: _headers,
|
||||
extra: _extra,
|
||||
)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/blogPosts/${id}/comments/show',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(
|
||||
baseUrl: _combineBaseUrls(
|
||||
_dio.options.baseUrl,
|
||||
baseUrl,
|
||||
)));
|
||||
final _result = await _dio.fetch<Map<String, dynamic>>(_options);
|
||||
late CommentModel _value;
|
||||
try {
|
||||
@@ -207,20 +241,32 @@ class _FeedService implements FeedService {
|
||||
queryParameters.removeWhere((k, v) => v == null);
|
||||
final _headers = <String, dynamic>{};
|
||||
final _data = FormData();
|
||||
_data.fields.add(MapEntry('body', body));
|
||||
_data.fields.add(MapEntry(
|
||||
'body',
|
||||
body,
|
||||
));
|
||||
if (parentCommentId != null) {
|
||||
_data.fields.add(MapEntry('parentCommentId', parentCommentId.toString()));
|
||||
_data.fields.add(MapEntry(
|
||||
'parentCommentId',
|
||||
parentCommentId.toString(),
|
||||
));
|
||||
}
|
||||
final _options = _setStreamType<void>(
|
||||
Options(method: 'POST', headers: _headers, extra: _extra)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/blogPosts/${id}/comment/create',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(baseUrl: _combineBaseUrls(_dio.options.baseUrl, baseUrl)),
|
||||
);
|
||||
final _options = _setStreamType<void>(Options(
|
||||
method: 'POST',
|
||||
headers: _headers,
|
||||
extra: _extra,
|
||||
)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/blogPosts/${id}/comment/create',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(
|
||||
baseUrl: _combineBaseUrls(
|
||||
_dio.options.baseUrl,
|
||||
baseUrl,
|
||||
)));
|
||||
await _dio.fetch<void>(_options);
|
||||
}
|
||||
|
||||
@@ -230,16 +276,22 @@ class _FeedService implements FeedService {
|
||||
final queryParameters = <String, dynamic>{};
|
||||
final _headers = <String, dynamic>{};
|
||||
const Map<String, dynamic>? _data = null;
|
||||
final _options = _setStreamType<CommentModel>(
|
||||
Options(method: 'GET', headers: _headers, extra: _extra)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/diets/${id}/comments/show',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(baseUrl: _combineBaseUrls(_dio.options.baseUrl, baseUrl)),
|
||||
);
|
||||
final _options = _setStreamType<CommentModel>(Options(
|
||||
method: 'GET',
|
||||
headers: _headers,
|
||||
extra: _extra,
|
||||
)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/diets/${id}/comments/show',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(
|
||||
baseUrl: _combineBaseUrls(
|
||||
_dio.options.baseUrl,
|
||||
baseUrl,
|
||||
)));
|
||||
final _result = await _dio.fetch<Map<String, dynamic>>(_options);
|
||||
late CommentModel _value;
|
||||
try {
|
||||
@@ -262,20 +314,32 @@ class _FeedService implements FeedService {
|
||||
queryParameters.removeWhere((k, v) => v == null);
|
||||
final _headers = <String, dynamic>{};
|
||||
final _data = FormData();
|
||||
_data.fields.add(MapEntry('body', body));
|
||||
_data.fields.add(MapEntry(
|
||||
'body',
|
||||
body,
|
||||
));
|
||||
if (parentCommentId != null) {
|
||||
_data.fields.add(MapEntry('parentCommentId', parentCommentId.toString()));
|
||||
_data.fields.add(MapEntry(
|
||||
'parentCommentId',
|
||||
parentCommentId.toString(),
|
||||
));
|
||||
}
|
||||
final _options = _setStreamType<void>(
|
||||
Options(method: 'POST', headers: _headers, extra: _extra)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/diets/${id}/comment/create',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(baseUrl: _combineBaseUrls(_dio.options.baseUrl, baseUrl)),
|
||||
);
|
||||
final _options = _setStreamType<void>(Options(
|
||||
method: 'POST',
|
||||
headers: _headers,
|
||||
extra: _extra,
|
||||
)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/diets/${id}/comment/create',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(
|
||||
baseUrl: _combineBaseUrls(
|
||||
_dio.options.baseUrl,
|
||||
baseUrl,
|
||||
)));
|
||||
await _dio.fetch<void>(_options);
|
||||
}
|
||||
|
||||
@@ -285,16 +349,22 @@ class _FeedService implements FeedService {
|
||||
final queryParameters = <String, dynamic>{};
|
||||
final _headers = <String, dynamic>{};
|
||||
const Map<String, dynamic>? _data = null;
|
||||
final _options = _setStreamType<CommentModel>(
|
||||
Options(method: 'GET', headers: _headers, extra: _extra)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/plans/${slug}/comments/show',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(baseUrl: _combineBaseUrls(_dio.options.baseUrl, baseUrl)),
|
||||
);
|
||||
final _options = _setStreamType<CommentModel>(Options(
|
||||
method: 'GET',
|
||||
headers: _headers,
|
||||
extra: _extra,
|
||||
)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/plans/${slug}/comments/show',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(
|
||||
baseUrl: _combineBaseUrls(
|
||||
_dio.options.baseUrl,
|
||||
baseUrl,
|
||||
)));
|
||||
final _result = await _dio.fetch<Map<String, dynamic>>(_options);
|
||||
late CommentModel _value;
|
||||
try {
|
||||
@@ -317,20 +387,32 @@ class _FeedService implements FeedService {
|
||||
queryParameters.removeWhere((k, v) => v == null);
|
||||
final _headers = <String, dynamic>{};
|
||||
final _data = FormData();
|
||||
_data.fields.add(MapEntry('body', body));
|
||||
_data.fields.add(MapEntry(
|
||||
'body',
|
||||
body,
|
||||
));
|
||||
if (parentCommentId != null) {
|
||||
_data.fields.add(MapEntry('parentCommentId', parentCommentId.toString()));
|
||||
_data.fields.add(MapEntry(
|
||||
'parentCommentId',
|
||||
parentCommentId.toString(),
|
||||
));
|
||||
}
|
||||
final _options = _setStreamType<void>(
|
||||
Options(method: 'POST', headers: _headers, extra: _extra)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/plans/${slug}/comment/create',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(baseUrl: _combineBaseUrls(_dio.options.baseUrl, baseUrl)),
|
||||
);
|
||||
final _options = _setStreamType<void>(Options(
|
||||
method: 'POST',
|
||||
headers: _headers,
|
||||
extra: _extra,
|
||||
)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/plans/${slug}/comment/create',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(
|
||||
baseUrl: _combineBaseUrls(
|
||||
_dio.options.baseUrl,
|
||||
baseUrl,
|
||||
)));
|
||||
await _dio.fetch<void>(_options);
|
||||
}
|
||||
|
||||
@@ -340,16 +422,22 @@ class _FeedService implements FeedService {
|
||||
final queryParameters = <String, dynamic>{};
|
||||
final _headers = <String, dynamic>{};
|
||||
const Map<String, dynamic>? _data = null;
|
||||
final _options = _setStreamType<CommentModel>(
|
||||
Options(method: 'GET', headers: _headers, extra: _extra)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/recipes/${id}/comments/show',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(baseUrl: _combineBaseUrls(_dio.options.baseUrl, baseUrl)),
|
||||
);
|
||||
final _options = _setStreamType<CommentModel>(Options(
|
||||
method: 'GET',
|
||||
headers: _headers,
|
||||
extra: _extra,
|
||||
)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/recipes/${id}/comments/show',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(
|
||||
baseUrl: _combineBaseUrls(
|
||||
_dio.options.baseUrl,
|
||||
baseUrl,
|
||||
)));
|
||||
final _result = await _dio.fetch<Map<String, dynamic>>(_options);
|
||||
late CommentModel _value;
|
||||
try {
|
||||
@@ -372,20 +460,32 @@ class _FeedService implements FeedService {
|
||||
queryParameters.removeWhere((k, v) => v == null);
|
||||
final _headers = <String, dynamic>{};
|
||||
final _data = FormData();
|
||||
_data.fields.add(MapEntry('body', body));
|
||||
_data.fields.add(MapEntry(
|
||||
'body',
|
||||
body,
|
||||
));
|
||||
if (parentCommentId != null) {
|
||||
_data.fields.add(MapEntry('parentCommentId', parentCommentId.toString()));
|
||||
_data.fields.add(MapEntry(
|
||||
'parentCommentId',
|
||||
parentCommentId.toString(),
|
||||
));
|
||||
}
|
||||
final _options = _setStreamType<void>(
|
||||
Options(method: 'POST', headers: _headers, extra: _extra)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/recipes/${id}/comment/create',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(baseUrl: _combineBaseUrls(_dio.options.baseUrl, baseUrl)),
|
||||
);
|
||||
final _options = _setStreamType<void>(Options(
|
||||
method: 'POST',
|
||||
headers: _headers,
|
||||
extra: _extra,
|
||||
)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/recipes/${id}/comment/create',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(
|
||||
baseUrl: _combineBaseUrls(
|
||||
_dio.options.baseUrl,
|
||||
baseUrl,
|
||||
)));
|
||||
await _dio.fetch<void>(_options);
|
||||
}
|
||||
|
||||
@@ -395,16 +495,22 @@ class _FeedService implements FeedService {
|
||||
final queryParameters = <String, dynamic>{};
|
||||
final _headers = <String, dynamic>{};
|
||||
const Map<String, dynamic>? _data = null;
|
||||
final _options = _setStreamType<void>(
|
||||
Options(method: 'POST', headers: _headers, extra: _extra)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/blogPosts/${id}/like',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(baseUrl: _combineBaseUrls(_dio.options.baseUrl, baseUrl)),
|
||||
);
|
||||
final _options = _setStreamType<void>(Options(
|
||||
method: 'POST',
|
||||
headers: _headers,
|
||||
extra: _extra,
|
||||
)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/blogPosts/${id}/like',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(
|
||||
baseUrl: _combineBaseUrls(
|
||||
_dio.options.baseUrl,
|
||||
baseUrl,
|
||||
)));
|
||||
await _dio.fetch<void>(_options);
|
||||
}
|
||||
|
||||
@@ -414,16 +520,22 @@ class _FeedService implements FeedService {
|
||||
final queryParameters = <String, dynamic>{};
|
||||
final _headers = <String, dynamic>{};
|
||||
const Map<String, dynamic>? _data = null;
|
||||
final _options = _setStreamType<void>(
|
||||
Options(method: 'POST', headers: _headers, extra: _extra)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/blogPosts/${id}/unliked',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(baseUrl: _combineBaseUrls(_dio.options.baseUrl, baseUrl)),
|
||||
);
|
||||
final _options = _setStreamType<void>(Options(
|
||||
method: 'POST',
|
||||
headers: _headers,
|
||||
extra: _extra,
|
||||
)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/blogPosts/${id}/unliked',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(
|
||||
baseUrl: _combineBaseUrls(
|
||||
_dio.options.baseUrl,
|
||||
baseUrl,
|
||||
)));
|
||||
await _dio.fetch<void>(_options);
|
||||
}
|
||||
|
||||
@@ -433,16 +545,22 @@ class _FeedService implements FeedService {
|
||||
final queryParameters = <String, dynamic>{};
|
||||
final _headers = <String, dynamic>{};
|
||||
const Map<String, dynamic>? _data = null;
|
||||
final _options = _setStreamType<FeedConsultantPaginationModel>(
|
||||
Options(method: 'GET', headers: _headers, extra: _extra)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/consultants/index',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(baseUrl: _combineBaseUrls(_dio.options.baseUrl, baseUrl)),
|
||||
);
|
||||
final _options = _setStreamType<FeedConsultantPaginationModel>(Options(
|
||||
method: 'GET',
|
||||
headers: _headers,
|
||||
extra: _extra,
|
||||
)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/consultants/index',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(
|
||||
baseUrl: _combineBaseUrls(
|
||||
_dio.options.baseUrl,
|
||||
baseUrl,
|
||||
)));
|
||||
final _result = await _dio.fetch<Map<String, dynamic>>(_options);
|
||||
late FeedConsultantPaginationModel _value;
|
||||
try {
|
||||
@@ -467,7 +585,10 @@ class _FeedService implements FeedService {
|
||||
return requestOptions;
|
||||
}
|
||||
|
||||
String _combineBaseUrls(String dioBaseUrl, String? baseUrl) {
|
||||
String _combineBaseUrls(
|
||||
String dioBaseUrl,
|
||||
String? baseUrl,
|
||||
) {
|
||||
if (baseUrl == null || baseUrl.trim().isEmpty) {
|
||||
return dioBaseUrl;
|
||||
}
|
||||
|
||||
@@ -9,7 +9,11 @@ part of 'glossary_service.dart';
|
||||
// ignore_for_file: unnecessary_brace_in_string_interps,no_leading_underscores_for_local_identifiers,unused_element,unnecessary_string_interpolations
|
||||
|
||||
class _GlossaryService implements GlossaryService {
|
||||
_GlossaryService(this._dio, {this.baseUrl, this.errorLogger});
|
||||
_GlossaryService(
|
||||
this._dio, {
|
||||
this.baseUrl,
|
||||
this.errorLogger,
|
||||
});
|
||||
|
||||
final Dio _dio;
|
||||
|
||||
@@ -18,23 +22,28 @@ class _GlossaryService implements GlossaryService {
|
||||
final ParseErrorLogger? errorLogger;
|
||||
|
||||
@override
|
||||
Future<GlossaryPaginationModel> getGlossaryByQuery({
|
||||
required String query,
|
||||
}) async {
|
||||
Future<GlossaryPaginationModel> getGlossaryByQuery(
|
||||
{required String query}) async {
|
||||
final _extra = <String, dynamic>{};
|
||||
final queryParameters = <String, dynamic>{r'search': query};
|
||||
final _headers = <String, dynamic>{};
|
||||
const Map<String, dynamic>? _data = null;
|
||||
final _options = _setStreamType<GlossaryPaginationModel>(
|
||||
Options(method: 'GET', headers: _headers, extra: _extra)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/glossaries/search',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(baseUrl: _combineBaseUrls(_dio.options.baseUrl, baseUrl)),
|
||||
);
|
||||
final _options = _setStreamType<GlossaryPaginationModel>(Options(
|
||||
method: 'GET',
|
||||
headers: _headers,
|
||||
extra: _extra,
|
||||
)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/glossaries/search',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(
|
||||
baseUrl: _combineBaseUrls(
|
||||
_dio.options.baseUrl,
|
||||
baseUrl,
|
||||
)));
|
||||
final _result = await _dio.fetch<Map<String, dynamic>>(_options);
|
||||
late GlossaryPaginationModel _value;
|
||||
try {
|
||||
@@ -59,7 +68,10 @@ class _GlossaryService implements GlossaryService {
|
||||
return requestOptions;
|
||||
}
|
||||
|
||||
String _combineBaseUrls(String dioBaseUrl, String? baseUrl) {
|
||||
String _combineBaseUrls(
|
||||
String dioBaseUrl,
|
||||
String? baseUrl,
|
||||
) {
|
||||
if (baseUrl == null || baseUrl.trim().isEmpty) {
|
||||
return dioBaseUrl;
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import 'package:eatvio_app/core/token_storage.dart';
|
||||
import 'package:eatvio_app/core/utils/image_constant.dart';
|
||||
import 'package:eatvio_app/core/locator_service.dart';
|
||||
import 'package:eatvio_app/core/theme/theme_helper.dart';
|
||||
import 'package:eatvio_app/features/dev_tools/presentation/dev_tools_screen.dart';
|
||||
import 'package:eatvio_app/features/my_diets/presentation/my_diets_screen.dart';
|
||||
import 'package:eatvio_app/features/my_plans/presentation/my_plans_screen.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
@@ -65,6 +66,14 @@ class MenuScreen extends StatelessWidget {
|
||||
onTap: () => GoRouter.of(context).push('/support-screen'),
|
||||
),
|
||||
_divider(context),
|
||||
_tile(
|
||||
leading: ImageConstant.icnSupport,
|
||||
title: 'Для разработчиков',
|
||||
onTap: () {
|
||||
GoRouter.of(context).pushNamed(DevToolsScreen.name);
|
||||
},
|
||||
),
|
||||
_divider(context),
|
||||
_tile(
|
||||
leading: ImageConstant.icnExit,
|
||||
title: 'Выход',
|
||||
|
||||
@@ -9,7 +9,7 @@ abstract class MyDietsService {
|
||||
|
||||
factory MyDietsService(Dio dio, {String baseUrl}) = _MyDietsService;
|
||||
|
||||
@GET('/api/diets/index')
|
||||
@GET('/api/profile/my_diets')
|
||||
Future<DietsPagination> getDiets({
|
||||
@Query('page') required int page,
|
||||
@Query('filters[name][\$startsWith]') String? query,
|
||||
|
||||
@@ -9,7 +9,11 @@ part of 'my_diets_service.dart';
|
||||
// ignore_for_file: unnecessary_brace_in_string_interps,no_leading_underscores_for_local_identifiers,unused_element,unnecessary_string_interpolations
|
||||
|
||||
class _MyDietsService implements MyDietsService {
|
||||
_MyDietsService(this._dio, {this.baseUrl, this.errorLogger});
|
||||
_MyDietsService(
|
||||
this._dio, {
|
||||
this.baseUrl,
|
||||
this.errorLogger,
|
||||
});
|
||||
|
||||
final Dio _dio;
|
||||
|
||||
@@ -36,16 +40,22 @@ class _MyDietsService implements MyDietsService {
|
||||
queryParameters.removeWhere((k, v) => v == null);
|
||||
final _headers = <String, dynamic>{};
|
||||
const Map<String, dynamic>? _data = null;
|
||||
final _options = _setStreamType<DietsPagination>(
|
||||
Options(method: 'GET', headers: _headers, extra: _extra)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/diets/index',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(baseUrl: _combineBaseUrls(_dio.options.baseUrl, baseUrl)),
|
||||
);
|
||||
final _options = _setStreamType<DietsPagination>(Options(
|
||||
method: 'GET',
|
||||
headers: _headers,
|
||||
extra: _extra,
|
||||
)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/profile/my_diets',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(
|
||||
baseUrl: _combineBaseUrls(
|
||||
_dio.options.baseUrl,
|
||||
baseUrl,
|
||||
)));
|
||||
final _result = await _dio.fetch<Map<String, dynamic>>(_options);
|
||||
late DietsPagination _value;
|
||||
try {
|
||||
@@ -63,16 +73,22 @@ class _MyDietsService implements MyDietsService {
|
||||
final queryParameters = <String, dynamic>{};
|
||||
final _headers = <String, dynamic>{};
|
||||
const Map<String, dynamic>? _data = null;
|
||||
final _options = _setStreamType<void>(
|
||||
Options(method: 'POST', headers: _headers, extra: _extra)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/diets/delete/${dietId}',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(baseUrl: _combineBaseUrls(_dio.options.baseUrl, baseUrl)),
|
||||
);
|
||||
final _options = _setStreamType<void>(Options(
|
||||
method: 'POST',
|
||||
headers: _headers,
|
||||
extra: _extra,
|
||||
)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/diets/delete/${dietId}',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(
|
||||
baseUrl: _combineBaseUrls(
|
||||
_dio.options.baseUrl,
|
||||
baseUrl,
|
||||
)));
|
||||
await _dio.fetch<void>(_options);
|
||||
}
|
||||
|
||||
@@ -89,7 +105,10 @@ class _MyDietsService implements MyDietsService {
|
||||
return requestOptions;
|
||||
}
|
||||
|
||||
String _combineBaseUrls(String dioBaseUrl, String? baseUrl) {
|
||||
String _combineBaseUrls(
|
||||
String dioBaseUrl,
|
||||
String? baseUrl,
|
||||
) {
|
||||
if (baseUrl == null || baseUrl.trim().isEmpty) {
|
||||
return dioBaseUrl;
|
||||
}
|
||||
|
||||
@@ -9,7 +9,11 @@ part of 'my_plans_service.dart';
|
||||
// ignore_for_file: unnecessary_brace_in_string_interps,no_leading_underscores_for_local_identifiers,unused_element,unnecessary_string_interpolations
|
||||
|
||||
class _MyPlansService implements MyPlansService {
|
||||
_MyPlansService(this._dio, {this.baseUrl, this.errorLogger});
|
||||
_MyPlansService(
|
||||
this._dio, {
|
||||
this.baseUrl,
|
||||
this.errorLogger,
|
||||
});
|
||||
|
||||
final Dio _dio;
|
||||
|
||||
@@ -38,16 +42,22 @@ class _MyPlansService implements MyPlansService {
|
||||
queryParameters.removeWhere((k, v) => v == null);
|
||||
final _headers = <String, dynamic>{};
|
||||
const Map<String, dynamic>? _data = null;
|
||||
final _options = _setStreamType<PlanPaginationModel>(
|
||||
Options(method: 'GET', headers: _headers, extra: _extra)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/plans/index',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(baseUrl: _combineBaseUrls(_dio.options.baseUrl, baseUrl)),
|
||||
);
|
||||
final _options = _setStreamType<PlanPaginationModel>(Options(
|
||||
method: 'GET',
|
||||
headers: _headers,
|
||||
extra: _extra,
|
||||
)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/plans/index',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(
|
||||
baseUrl: _combineBaseUrls(
|
||||
_dio.options.baseUrl,
|
||||
baseUrl,
|
||||
)));
|
||||
final _result = await _dio.fetch<Map<String, dynamic>>(_options);
|
||||
late PlanPaginationModel _value;
|
||||
try {
|
||||
@@ -65,16 +75,22 @@ class _MyPlansService implements MyPlansService {
|
||||
final queryParameters = <String, dynamic>{};
|
||||
final _headers = <String, dynamic>{};
|
||||
const Map<String, dynamic>? _data = null;
|
||||
final _options = _setStreamType<void>(
|
||||
Options(method: 'POST', headers: _headers, extra: _extra)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/plans/delete/${slug}',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(baseUrl: _combineBaseUrls(_dio.options.baseUrl, baseUrl)),
|
||||
);
|
||||
final _options = _setStreamType<void>(Options(
|
||||
method: 'POST',
|
||||
headers: _headers,
|
||||
extra: _extra,
|
||||
)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/plans/delete/${slug}',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(
|
||||
baseUrl: _combineBaseUrls(
|
||||
_dio.options.baseUrl,
|
||||
baseUrl,
|
||||
)));
|
||||
await _dio.fetch<void>(_options);
|
||||
}
|
||||
|
||||
@@ -91,7 +107,10 @@ class _MyPlansService implements MyPlansService {
|
||||
return requestOptions;
|
||||
}
|
||||
|
||||
String _combineBaseUrls(String dioBaseUrl, String? baseUrl) {
|
||||
String _combineBaseUrls(
|
||||
String dioBaseUrl,
|
||||
String? baseUrl,
|
||||
) {
|
||||
if (baseUrl == null || baseUrl.trim().isEmpty) {
|
||||
return dioBaseUrl;
|
||||
}
|
||||
|
||||
@@ -363,13 +363,11 @@ class _AboutPlanScreenState extends State<AboutPlanScreen> {
|
||||
'assets/icons/heart.svg',
|
||||
width: 14,
|
||||
height: 12,
|
||||
|
||||
/// TODO задача для бека на добавление wasLokedByMe?
|
||||
colorFilter: ColorFilter.mode(appTheme.blueA400, BlendMode.srcIn),
|
||||
colorFilter: state.planModel?.wasLikedByMe == true ? ColorFilter.mode(appTheme.blueA400, BlendMode.srcIn) : null,
|
||||
),
|
||||
SizedBox(width: 8),
|
||||
Text(
|
||||
widget.plan.totalLikes.toString(),
|
||||
state.planModel?.totalLikes.toString() ?? '0',
|
||||
style: TextStyles.textXSSemibold.copyWith(color: appTheme.black),
|
||||
),
|
||||
],
|
||||
|
||||
@@ -9,7 +9,11 @@ part of 'plan_service.dart';
|
||||
// ignore_for_file: unnecessary_brace_in_string_interps,no_leading_underscores_for_local_identifiers,unused_element,unnecessary_string_interpolations
|
||||
|
||||
class _PlanService implements PlanService {
|
||||
_PlanService(this._dio, {this.baseUrl, this.errorLogger});
|
||||
_PlanService(
|
||||
this._dio, {
|
||||
this.baseUrl,
|
||||
this.errorLogger,
|
||||
});
|
||||
|
||||
final Dio _dio;
|
||||
|
||||
@@ -23,16 +27,22 @@ class _PlanService implements PlanService {
|
||||
final queryParameters = <String, dynamic>{};
|
||||
final _headers = <String, dynamic>{};
|
||||
const Map<String, dynamic>? _data = null;
|
||||
final _options = _setStreamType<PlanModel>(
|
||||
Options(method: 'GET', headers: _headers, extra: _extra)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/plans/show/${slug}',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(baseUrl: _combineBaseUrls(_dio.options.baseUrl, baseUrl)),
|
||||
);
|
||||
final _options = _setStreamType<PlanModel>(Options(
|
||||
method: 'GET',
|
||||
headers: _headers,
|
||||
extra: _extra,
|
||||
)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/plans/show/${slug}',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(
|
||||
baseUrl: _combineBaseUrls(
|
||||
_dio.options.baseUrl,
|
||||
baseUrl,
|
||||
)));
|
||||
final _result = await _dio.fetch<Map<String, dynamic>>(_options);
|
||||
late PlanModel _value;
|
||||
try {
|
||||
@@ -50,16 +60,22 @@ class _PlanService implements PlanService {
|
||||
final queryParameters = <String, dynamic>{};
|
||||
final _headers = <String, dynamic>{};
|
||||
const Map<String, dynamic>? _data = null;
|
||||
final _options = _setStreamType<void>(
|
||||
Options(method: 'POST', headers: _headers, extra: _extra)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/plans/${slug}/like',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(baseUrl: _combineBaseUrls(_dio.options.baseUrl, baseUrl)),
|
||||
);
|
||||
final _options = _setStreamType<void>(Options(
|
||||
method: 'POST',
|
||||
headers: _headers,
|
||||
extra: _extra,
|
||||
)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/plans/${slug}/like',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(
|
||||
baseUrl: _combineBaseUrls(
|
||||
_dio.options.baseUrl,
|
||||
baseUrl,
|
||||
)));
|
||||
await _dio.fetch<void>(_options);
|
||||
}
|
||||
|
||||
@@ -69,16 +85,22 @@ class _PlanService implements PlanService {
|
||||
final queryParameters = <String, dynamic>{};
|
||||
final _headers = <String, dynamic>{};
|
||||
const Map<String, dynamic>? _data = null;
|
||||
final _options = _setStreamType<void>(
|
||||
Options(method: 'POST', headers: _headers, extra: _extra)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/plans/${slug}/add_to_favorite',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(baseUrl: _combineBaseUrls(_dio.options.baseUrl, baseUrl)),
|
||||
);
|
||||
final _options = _setStreamType<void>(Options(
|
||||
method: 'POST',
|
||||
headers: _headers,
|
||||
extra: _extra,
|
||||
)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/plans/${slug}/add_to_favorite',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(
|
||||
baseUrl: _combineBaseUrls(
|
||||
_dio.options.baseUrl,
|
||||
baseUrl,
|
||||
)));
|
||||
await _dio.fetch<void>(_options);
|
||||
}
|
||||
|
||||
@@ -88,16 +110,22 @@ class _PlanService implements PlanService {
|
||||
final queryParameters = <String, dynamic>{};
|
||||
final _headers = <String, dynamic>{};
|
||||
const Map<String, dynamic>? _data = null;
|
||||
final _options = _setStreamType<void>(
|
||||
Options(method: 'POST', headers: _headers, extra: _extra)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/plans/${slug}/remove_from_favorite',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(baseUrl: _combineBaseUrls(_dio.options.baseUrl, baseUrl)),
|
||||
);
|
||||
final _options = _setStreamType<void>(Options(
|
||||
method: 'POST',
|
||||
headers: _headers,
|
||||
extra: _extra,
|
||||
)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/plans/${slug}/remove_from_favorite',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(
|
||||
baseUrl: _combineBaseUrls(
|
||||
_dio.options.baseUrl,
|
||||
baseUrl,
|
||||
)));
|
||||
await _dio.fetch<void>(_options);
|
||||
}
|
||||
|
||||
@@ -114,7 +142,10 @@ class _PlanService implements PlanService {
|
||||
return requestOptions;
|
||||
}
|
||||
|
||||
String _combineBaseUrls(String dioBaseUrl, String? baseUrl) {
|
||||
String _combineBaseUrls(
|
||||
String dioBaseUrl,
|
||||
String? baseUrl,
|
||||
) {
|
||||
if (baseUrl == null || baseUrl.trim().isEmpty) {
|
||||
return dioBaseUrl;
|
||||
}
|
||||
|
||||
@@ -9,7 +9,11 @@ part of 'plans_service.dart';
|
||||
// ignore_for_file: unnecessary_brace_in_string_interps,no_leading_underscores_for_local_identifiers,unused_element,unnecessary_string_interpolations
|
||||
|
||||
class _PlansService implements PlansService {
|
||||
_PlansService(this._dio, {this.baseUrl, this.errorLogger});
|
||||
_PlansService(
|
||||
this._dio, {
|
||||
this.baseUrl,
|
||||
this.errorLogger,
|
||||
});
|
||||
|
||||
final Dio _dio;
|
||||
|
||||
@@ -23,16 +27,22 @@ class _PlansService implements PlansService {
|
||||
final queryParameters = <String, dynamic>{};
|
||||
final _headers = <String, dynamic>{};
|
||||
const Map<String, dynamic>? _data = null;
|
||||
final _options = _setStreamType<PlanPaginationModel>(
|
||||
Options(method: 'GET', headers: _headers, extra: _extra)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/plans/get_by_author/${author}',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(baseUrl: _combineBaseUrls(_dio.options.baseUrl, baseUrl)),
|
||||
);
|
||||
final _options = _setStreamType<PlanPaginationModel>(Options(
|
||||
method: 'GET',
|
||||
headers: _headers,
|
||||
extra: _extra,
|
||||
)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/plans/get_by_author/${author}',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(
|
||||
baseUrl: _combineBaseUrls(
|
||||
_dio.options.baseUrl,
|
||||
baseUrl,
|
||||
)));
|
||||
final _result = await _dio.fetch<Map<String, dynamic>>(_options);
|
||||
late PlanPaginationModel _value;
|
||||
try {
|
||||
@@ -57,7 +67,10 @@ class _PlansService implements PlansService {
|
||||
return requestOptions;
|
||||
}
|
||||
|
||||
String _combineBaseUrls(String dioBaseUrl, String? baseUrl) {
|
||||
String _combineBaseUrls(
|
||||
String dioBaseUrl,
|
||||
String? baseUrl,
|
||||
) {
|
||||
if (baseUrl == null || baseUrl.trim().isEmpty) {
|
||||
return dioBaseUrl;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
import 'package:eatvio_app/features/feed/models/feed_blog_post_model.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
|
||||
part 'chosen_diets_pagination_model.freezed.dart';
|
||||
part 'chosen_diets_pagination_model.g.dart';
|
||||
|
||||
@freezed
|
||||
class ChosenDietsPaginationModel with _$ChosenDietsPaginationModel {
|
||||
factory ChosenDietsPaginationModel({
|
||||
@JsonKey(name: 'data') required List<ChosenDietModel> diets,
|
||||
}) = _ChosenDietsPaginationModel;
|
||||
|
||||
factory ChosenDietsPaginationModel.fromJson(Map<String, dynamic> json) => _$ChosenDietsPaginationModelFromJson(json);
|
||||
}
|
||||
|
||||
@freezed
|
||||
class ChosenDietModel with _$ChosenDietModel {
|
||||
factory ChosenDietModel({
|
||||
@JsonKey(name: 'id') required int chosenDietID,
|
||||
@JsonKey(name: 'chosen_plan_id') required int chosenPlanId,
|
||||
@JsonKey() required String state,
|
||||
@JsonKey(name: 'start_date', fromJson: parseDate) required DateTime startDate,
|
||||
@JsonKey(name: 'diet', fromJson: _parseDietId) required int? dietId,
|
||||
}) = _ChosenDietModel;
|
||||
|
||||
factory ChosenDietModel.fromJson(Map<String, dynamic> json) => _$ChosenDietModelFromJson(json);
|
||||
}
|
||||
|
||||
int? _parseDietId(json) {
|
||||
if (json == null) return null;
|
||||
return json['id'] as int?;
|
||||
}
|
||||
@@ -0,0 +1,441 @@
|
||||
// coverage:ignore-file
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
// ignore_for_file: type=lint
|
||||
// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark
|
||||
|
||||
part of 'chosen_diets_pagination_model.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// FreezedGenerator
|
||||
// **************************************************************************
|
||||
|
||||
T _$identity<T>(T value) => value;
|
||||
|
||||
final _privateConstructorUsedError = UnsupportedError(
|
||||
'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#adding-getters-and-methods-to-our-models');
|
||||
|
||||
ChosenDietsPaginationModel _$ChosenDietsPaginationModelFromJson(
|
||||
Map<String, dynamic> json) {
|
||||
return _ChosenDietsPaginationModel.fromJson(json);
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
mixin _$ChosenDietsPaginationModel {
|
||||
@JsonKey(name: 'data')
|
||||
List<ChosenDietModel> get diets => throw _privateConstructorUsedError;
|
||||
|
||||
/// Serializes this ChosenDietsPaginationModel to a JSON map.
|
||||
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
|
||||
|
||||
/// Create a copy of ChosenDietsPaginationModel
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
$ChosenDietsPaginationModelCopyWith<ChosenDietsPaginationModel>
|
||||
get copyWith => throw _privateConstructorUsedError;
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract class $ChosenDietsPaginationModelCopyWith<$Res> {
|
||||
factory $ChosenDietsPaginationModelCopyWith(ChosenDietsPaginationModel value,
|
||||
$Res Function(ChosenDietsPaginationModel) then) =
|
||||
_$ChosenDietsPaginationModelCopyWithImpl<$Res,
|
||||
ChosenDietsPaginationModel>;
|
||||
@useResult
|
||||
$Res call({@JsonKey(name: 'data') List<ChosenDietModel> diets});
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
class _$ChosenDietsPaginationModelCopyWithImpl<$Res,
|
||||
$Val extends ChosenDietsPaginationModel>
|
||||
implements $ChosenDietsPaginationModelCopyWith<$Res> {
|
||||
_$ChosenDietsPaginationModelCopyWithImpl(this._value, this._then);
|
||||
|
||||
// ignore: unused_field
|
||||
final $Val _value;
|
||||
// ignore: unused_field
|
||||
final $Res Function($Val) _then;
|
||||
|
||||
/// Create a copy of ChosenDietsPaginationModel
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@pragma('vm:prefer-inline')
|
||||
@override
|
||||
$Res call({
|
||||
Object? diets = null,
|
||||
}) {
|
||||
return _then(_value.copyWith(
|
||||
diets: null == diets
|
||||
? _value.diets
|
||||
: diets // ignore: cast_nullable_to_non_nullable
|
||||
as List<ChosenDietModel>,
|
||||
) as $Val);
|
||||
}
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract class _$$ChosenDietsPaginationModelImplCopyWith<$Res>
|
||||
implements $ChosenDietsPaginationModelCopyWith<$Res> {
|
||||
factory _$$ChosenDietsPaginationModelImplCopyWith(
|
||||
_$ChosenDietsPaginationModelImpl value,
|
||||
$Res Function(_$ChosenDietsPaginationModelImpl) then) =
|
||||
__$$ChosenDietsPaginationModelImplCopyWithImpl<$Res>;
|
||||
@override
|
||||
@useResult
|
||||
$Res call({@JsonKey(name: 'data') List<ChosenDietModel> diets});
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
class __$$ChosenDietsPaginationModelImplCopyWithImpl<$Res>
|
||||
extends _$ChosenDietsPaginationModelCopyWithImpl<$Res,
|
||||
_$ChosenDietsPaginationModelImpl>
|
||||
implements _$$ChosenDietsPaginationModelImplCopyWith<$Res> {
|
||||
__$$ChosenDietsPaginationModelImplCopyWithImpl(
|
||||
_$ChosenDietsPaginationModelImpl _value,
|
||||
$Res Function(_$ChosenDietsPaginationModelImpl) _then)
|
||||
: super(_value, _then);
|
||||
|
||||
/// Create a copy of ChosenDietsPaginationModel
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@pragma('vm:prefer-inline')
|
||||
@override
|
||||
$Res call({
|
||||
Object? diets = null,
|
||||
}) {
|
||||
return _then(_$ChosenDietsPaginationModelImpl(
|
||||
diets: null == diets
|
||||
? _value._diets
|
||||
: diets // ignore: cast_nullable_to_non_nullable
|
||||
as List<ChosenDietModel>,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
@JsonSerializable()
|
||||
class _$ChosenDietsPaginationModelImpl implements _ChosenDietsPaginationModel {
|
||||
_$ChosenDietsPaginationModelImpl(
|
||||
{@JsonKey(name: 'data') required final List<ChosenDietModel> diets})
|
||||
: _diets = diets;
|
||||
|
||||
factory _$ChosenDietsPaginationModelImpl.fromJson(
|
||||
Map<String, dynamic> json) =>
|
||||
_$$ChosenDietsPaginationModelImplFromJson(json);
|
||||
|
||||
final List<ChosenDietModel> _diets;
|
||||
@override
|
||||
@JsonKey(name: 'data')
|
||||
List<ChosenDietModel> get diets {
|
||||
if (_diets is EqualUnmodifiableListView) return _diets;
|
||||
// ignore: implicit_dynamic_type
|
||||
return EqualUnmodifiableListView(_diets);
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'ChosenDietsPaginationModel(diets: $diets)';
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) ||
|
||||
(other.runtimeType == runtimeType &&
|
||||
other is _$ChosenDietsPaginationModelImpl &&
|
||||
const DeepCollectionEquality().equals(other._diets, _diets));
|
||||
}
|
||||
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@override
|
||||
int get hashCode =>
|
||||
Object.hash(runtimeType, const DeepCollectionEquality().hash(_diets));
|
||||
|
||||
/// Create a copy of ChosenDietsPaginationModel
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@override
|
||||
@pragma('vm:prefer-inline')
|
||||
_$$ChosenDietsPaginationModelImplCopyWith<_$ChosenDietsPaginationModelImpl>
|
||||
get copyWith => __$$ChosenDietsPaginationModelImplCopyWithImpl<
|
||||
_$ChosenDietsPaginationModelImpl>(this, _$identity);
|
||||
|
||||
@override
|
||||
Map<String, dynamic> toJson() {
|
||||
return _$$ChosenDietsPaginationModelImplToJson(
|
||||
this,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
abstract class _ChosenDietsPaginationModel
|
||||
implements ChosenDietsPaginationModel {
|
||||
factory _ChosenDietsPaginationModel(
|
||||
{@JsonKey(name: 'data') required final List<ChosenDietModel> diets}) =
|
||||
_$ChosenDietsPaginationModelImpl;
|
||||
|
||||
factory _ChosenDietsPaginationModel.fromJson(Map<String, dynamic> json) =
|
||||
_$ChosenDietsPaginationModelImpl.fromJson;
|
||||
|
||||
@override
|
||||
@JsonKey(name: 'data')
|
||||
List<ChosenDietModel> get diets;
|
||||
|
||||
/// Create a copy of ChosenDietsPaginationModel
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
_$$ChosenDietsPaginationModelImplCopyWith<_$ChosenDietsPaginationModelImpl>
|
||||
get copyWith => throw _privateConstructorUsedError;
|
||||
}
|
||||
|
||||
ChosenDietModel _$ChosenDietModelFromJson(Map<String, dynamic> json) {
|
||||
return _ChosenDietModel.fromJson(json);
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
mixin _$ChosenDietModel {
|
||||
@JsonKey(name: 'id')
|
||||
int get chosenDietID => throw _privateConstructorUsedError;
|
||||
@JsonKey(name: 'chosen_plan_id')
|
||||
int get chosenPlanId => throw _privateConstructorUsedError;
|
||||
@JsonKey()
|
||||
String get state => throw _privateConstructorUsedError;
|
||||
@JsonKey(name: 'start_date', fromJson: parseDate)
|
||||
DateTime get startDate => throw _privateConstructorUsedError;
|
||||
@JsonKey(name: 'diet', fromJson: _parseDietId)
|
||||
int? get dietId => throw _privateConstructorUsedError;
|
||||
|
||||
/// Serializes this ChosenDietModel to a JSON map.
|
||||
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
|
||||
|
||||
/// Create a copy of ChosenDietModel
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
$ChosenDietModelCopyWith<ChosenDietModel> get copyWith =>
|
||||
throw _privateConstructorUsedError;
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract class $ChosenDietModelCopyWith<$Res> {
|
||||
factory $ChosenDietModelCopyWith(
|
||||
ChosenDietModel value, $Res Function(ChosenDietModel) then) =
|
||||
_$ChosenDietModelCopyWithImpl<$Res, ChosenDietModel>;
|
||||
@useResult
|
||||
$Res call(
|
||||
{@JsonKey(name: 'id') int chosenDietID,
|
||||
@JsonKey(name: 'chosen_plan_id') int chosenPlanId,
|
||||
@JsonKey() String state,
|
||||
@JsonKey(name: 'start_date', fromJson: parseDate) DateTime startDate,
|
||||
@JsonKey(name: 'diet', fromJson: _parseDietId) int? dietId});
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
class _$ChosenDietModelCopyWithImpl<$Res, $Val extends ChosenDietModel>
|
||||
implements $ChosenDietModelCopyWith<$Res> {
|
||||
_$ChosenDietModelCopyWithImpl(this._value, this._then);
|
||||
|
||||
// ignore: unused_field
|
||||
final $Val _value;
|
||||
// ignore: unused_field
|
||||
final $Res Function($Val) _then;
|
||||
|
||||
/// Create a copy of ChosenDietModel
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@pragma('vm:prefer-inline')
|
||||
@override
|
||||
$Res call({
|
||||
Object? chosenDietID = null,
|
||||
Object? chosenPlanId = null,
|
||||
Object? state = null,
|
||||
Object? startDate = null,
|
||||
Object? dietId = freezed,
|
||||
}) {
|
||||
return _then(_value.copyWith(
|
||||
chosenDietID: null == chosenDietID
|
||||
? _value.chosenDietID
|
||||
: chosenDietID // ignore: cast_nullable_to_non_nullable
|
||||
as int,
|
||||
chosenPlanId: null == chosenPlanId
|
||||
? _value.chosenPlanId
|
||||
: chosenPlanId // ignore: cast_nullable_to_non_nullable
|
||||
as int,
|
||||
state: null == state
|
||||
? _value.state
|
||||
: state // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
startDate: null == startDate
|
||||
? _value.startDate
|
||||
: startDate // ignore: cast_nullable_to_non_nullable
|
||||
as DateTime,
|
||||
dietId: freezed == dietId
|
||||
? _value.dietId
|
||||
: dietId // ignore: cast_nullable_to_non_nullable
|
||||
as int?,
|
||||
) as $Val);
|
||||
}
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract class _$$ChosenDietModelImplCopyWith<$Res>
|
||||
implements $ChosenDietModelCopyWith<$Res> {
|
||||
factory _$$ChosenDietModelImplCopyWith(_$ChosenDietModelImpl value,
|
||||
$Res Function(_$ChosenDietModelImpl) then) =
|
||||
__$$ChosenDietModelImplCopyWithImpl<$Res>;
|
||||
@override
|
||||
@useResult
|
||||
$Res call(
|
||||
{@JsonKey(name: 'id') int chosenDietID,
|
||||
@JsonKey(name: 'chosen_plan_id') int chosenPlanId,
|
||||
@JsonKey() String state,
|
||||
@JsonKey(name: 'start_date', fromJson: parseDate) DateTime startDate,
|
||||
@JsonKey(name: 'diet', fromJson: _parseDietId) int? dietId});
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
class __$$ChosenDietModelImplCopyWithImpl<$Res>
|
||||
extends _$ChosenDietModelCopyWithImpl<$Res, _$ChosenDietModelImpl>
|
||||
implements _$$ChosenDietModelImplCopyWith<$Res> {
|
||||
__$$ChosenDietModelImplCopyWithImpl(
|
||||
_$ChosenDietModelImpl _value, $Res Function(_$ChosenDietModelImpl) _then)
|
||||
: super(_value, _then);
|
||||
|
||||
/// Create a copy of ChosenDietModel
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@pragma('vm:prefer-inline')
|
||||
@override
|
||||
$Res call({
|
||||
Object? chosenDietID = null,
|
||||
Object? chosenPlanId = null,
|
||||
Object? state = null,
|
||||
Object? startDate = null,
|
||||
Object? dietId = freezed,
|
||||
}) {
|
||||
return _then(_$ChosenDietModelImpl(
|
||||
chosenDietID: null == chosenDietID
|
||||
? _value.chosenDietID
|
||||
: chosenDietID // ignore: cast_nullable_to_non_nullable
|
||||
as int,
|
||||
chosenPlanId: null == chosenPlanId
|
||||
? _value.chosenPlanId
|
||||
: chosenPlanId // ignore: cast_nullable_to_non_nullable
|
||||
as int,
|
||||
state: null == state
|
||||
? _value.state
|
||||
: state // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
startDate: null == startDate
|
||||
? _value.startDate
|
||||
: startDate // ignore: cast_nullable_to_non_nullable
|
||||
as DateTime,
|
||||
dietId: freezed == dietId
|
||||
? _value.dietId
|
||||
: dietId // ignore: cast_nullable_to_non_nullable
|
||||
as int?,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
@JsonSerializable()
|
||||
class _$ChosenDietModelImpl implements _ChosenDietModel {
|
||||
_$ChosenDietModelImpl(
|
||||
{@JsonKey(name: 'id') required this.chosenDietID,
|
||||
@JsonKey(name: 'chosen_plan_id') required this.chosenPlanId,
|
||||
@JsonKey() required this.state,
|
||||
@JsonKey(name: 'start_date', fromJson: parseDate) required this.startDate,
|
||||
@JsonKey(name: 'diet', fromJson: _parseDietId) required this.dietId});
|
||||
|
||||
factory _$ChosenDietModelImpl.fromJson(Map<String, dynamic> json) =>
|
||||
_$$ChosenDietModelImplFromJson(json);
|
||||
|
||||
@override
|
||||
@JsonKey(name: 'id')
|
||||
final int chosenDietID;
|
||||
@override
|
||||
@JsonKey(name: 'chosen_plan_id')
|
||||
final int chosenPlanId;
|
||||
@override
|
||||
@JsonKey()
|
||||
final String state;
|
||||
@override
|
||||
@JsonKey(name: 'start_date', fromJson: parseDate)
|
||||
final DateTime startDate;
|
||||
@override
|
||||
@JsonKey(name: 'diet', fromJson: _parseDietId)
|
||||
final int? dietId;
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'ChosenDietModel(chosenDietID: $chosenDietID, chosenPlanId: $chosenPlanId, state: $state, startDate: $startDate, dietId: $dietId)';
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) ||
|
||||
(other.runtimeType == runtimeType &&
|
||||
other is _$ChosenDietModelImpl &&
|
||||
(identical(other.chosenDietID, chosenDietID) ||
|
||||
other.chosenDietID == chosenDietID) &&
|
||||
(identical(other.chosenPlanId, chosenPlanId) ||
|
||||
other.chosenPlanId == chosenPlanId) &&
|
||||
(identical(other.state, state) || other.state == state) &&
|
||||
(identical(other.startDate, startDate) ||
|
||||
other.startDate == startDate) &&
|
||||
(identical(other.dietId, dietId) || other.dietId == dietId));
|
||||
}
|
||||
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@override
|
||||
int get hashCode => Object.hash(
|
||||
runtimeType, chosenDietID, chosenPlanId, state, startDate, dietId);
|
||||
|
||||
/// Create a copy of ChosenDietModel
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@override
|
||||
@pragma('vm:prefer-inline')
|
||||
_$$ChosenDietModelImplCopyWith<_$ChosenDietModelImpl> get copyWith =>
|
||||
__$$ChosenDietModelImplCopyWithImpl<_$ChosenDietModelImpl>(
|
||||
this, _$identity);
|
||||
|
||||
@override
|
||||
Map<String, dynamic> toJson() {
|
||||
return _$$ChosenDietModelImplToJson(
|
||||
this,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
abstract class _ChosenDietModel implements ChosenDietModel {
|
||||
factory _ChosenDietModel(
|
||||
{@JsonKey(name: 'id') required final int chosenDietID,
|
||||
@JsonKey(name: 'chosen_plan_id') required final int chosenPlanId,
|
||||
@JsonKey() required final String state,
|
||||
@JsonKey(name: 'start_date', fromJson: parseDate)
|
||||
required final DateTime startDate,
|
||||
@JsonKey(name: 'diet', fromJson: _parseDietId)
|
||||
required final int? dietId}) = _$ChosenDietModelImpl;
|
||||
|
||||
factory _ChosenDietModel.fromJson(Map<String, dynamic> json) =
|
||||
_$ChosenDietModelImpl.fromJson;
|
||||
|
||||
@override
|
||||
@JsonKey(name: 'id')
|
||||
int get chosenDietID;
|
||||
@override
|
||||
@JsonKey(name: 'chosen_plan_id')
|
||||
int get chosenPlanId;
|
||||
@override
|
||||
@JsonKey()
|
||||
String get state;
|
||||
@override
|
||||
@JsonKey(name: 'start_date', fromJson: parseDate)
|
||||
DateTime get startDate;
|
||||
@override
|
||||
@JsonKey(name: 'diet', fromJson: _parseDietId)
|
||||
int? get dietId;
|
||||
|
||||
/// Create a copy of ChosenDietModel
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
_$$ChosenDietModelImplCopyWith<_$ChosenDietModelImpl> get copyWith =>
|
||||
throw _privateConstructorUsedError;
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'chosen_diets_pagination_model.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// JsonSerializableGenerator
|
||||
// **************************************************************************
|
||||
|
||||
_$ChosenDietsPaginationModelImpl _$$ChosenDietsPaginationModelImplFromJson(
|
||||
Map<String, dynamic> json) =>
|
||||
_$ChosenDietsPaginationModelImpl(
|
||||
diets: (json['data'] as List<dynamic>)
|
||||
.map((e) => ChosenDietModel.fromJson(e as Map<String, dynamic>))
|
||||
.toList(),
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$$ChosenDietsPaginationModelImplToJson(
|
||||
_$ChosenDietsPaginationModelImpl instance) =>
|
||||
<String, dynamic>{
|
||||
'data': instance.diets,
|
||||
};
|
||||
|
||||
_$ChosenDietModelImpl _$$ChosenDietModelImplFromJson(
|
||||
Map<String, dynamic> json) =>
|
||||
_$ChosenDietModelImpl(
|
||||
chosenDietID: (json['id'] as num).toInt(),
|
||||
chosenPlanId: (json['chosen_plan_id'] as num).toInt(),
|
||||
state: json['state'] as String,
|
||||
startDate: parseDate(json['start_date'] as String),
|
||||
dietId: _parseDietId(json['diet']),
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$$ChosenDietModelImplToJson(
|
||||
_$ChosenDietModelImpl instance) =>
|
||||
<String, dynamic>{
|
||||
'id': instance.chosenDietID,
|
||||
'chosen_plan_id': instance.chosenPlanId,
|
||||
'state': instance.state,
|
||||
'start_date': instance.startDate.toIso8601String(),
|
||||
'diet': instance.dietId,
|
||||
};
|
||||
@@ -59,7 +59,6 @@ class _ProfileScreenState extends State<ProfileScreen> {
|
||||
late bool canSub;
|
||||
bool isFirstFetch = true;
|
||||
int _currentBullet = 0;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
@@ -338,7 +337,7 @@ class _ProfileScreenState extends State<ProfileScreen> {
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
|
||||
child: InkWell(
|
||||
onTap: () {
|
||||
GoRouter.of(context).pushNamed('blogPostCreateScreen');
|
||||
GoRouter.of(context).pushNamed('blogPostCreateScreen');
|
||||
},
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
child: Ink(
|
||||
|
||||
@@ -2,6 +2,7 @@ import 'dart:io';
|
||||
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:eatvio_app/features/feed/models/feed_blog_post_model.dart';
|
||||
import 'package:eatvio_app/features/profile/models/chosen_diets_pagination_model.dart';
|
||||
import 'package:eatvio_app/features/profile/models/circumference_model.dart';
|
||||
import 'package:eatvio_app/features/profile/models/profile_model.dart';
|
||||
import 'package:eatvio_app/features/profile/models/sub_model.dart';
|
||||
@@ -99,4 +100,7 @@ abstract class ProfileService {
|
||||
|
||||
@DELETE('/api/profile/photo/delete')
|
||||
Future<void> deletePhoto();
|
||||
|
||||
@GET('/api/profile/chosen_diets')
|
||||
Future<ChosenDietsPaginationModel> getChosenDiets();
|
||||
}
|
||||
|
||||
@@ -9,7 +9,11 @@ part of 'profile_service.dart';
|
||||
// ignore_for_file: unnecessary_brace_in_string_interps,no_leading_underscores_for_local_identifiers,unused_element,unnecessary_string_interpolations
|
||||
|
||||
class _ProfileService implements ProfileService {
|
||||
_ProfileService(this._dio, {this.baseUrl, this.errorLogger});
|
||||
_ProfileService(
|
||||
this._dio, {
|
||||
this.baseUrl,
|
||||
this.errorLogger,
|
||||
});
|
||||
|
||||
final Dio _dio;
|
||||
|
||||
@@ -23,16 +27,22 @@ class _ProfileService implements ProfileService {
|
||||
final queryParameters = <String, dynamic>{};
|
||||
final _headers = <String, dynamic>{};
|
||||
const Map<String, dynamic>? _data = null;
|
||||
final _options = _setStreamType<ProfileModel>(
|
||||
Options(method: 'GET', headers: _headers, extra: _extra)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/profile/show/${slug}',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(baseUrl: _combineBaseUrls(_dio.options.baseUrl, baseUrl)),
|
||||
);
|
||||
final _options = _setStreamType<ProfileModel>(Options(
|
||||
method: 'GET',
|
||||
headers: _headers,
|
||||
extra: _extra,
|
||||
)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/profile/show/${slug}',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(
|
||||
baseUrl: _combineBaseUrls(
|
||||
_dio.options.baseUrl,
|
||||
baseUrl,
|
||||
)));
|
||||
final _result = await _dio.fetch<Map<String, dynamic>>(_options);
|
||||
late ProfileModel _value;
|
||||
try {
|
||||
@@ -50,16 +60,22 @@ class _ProfileService implements ProfileService {
|
||||
final queryParameters = <String, dynamic>{};
|
||||
final _headers = <String, dynamic>{};
|
||||
const Map<String, dynamic>? _data = null;
|
||||
final _options = _setStreamType<ProfileModel>(
|
||||
Options(method: 'GET', headers: _headers, extra: _extra)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/profile/index',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(baseUrl: _combineBaseUrls(_dio.options.baseUrl, baseUrl)),
|
||||
);
|
||||
final _options = _setStreamType<ProfileModel>(Options(
|
||||
method: 'GET',
|
||||
headers: _headers,
|
||||
extra: _extra,
|
||||
)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/profile/index',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(
|
||||
baseUrl: _combineBaseUrls(
|
||||
_dio.options.baseUrl,
|
||||
baseUrl,
|
||||
)));
|
||||
final _result = await _dio.fetch<Map<String, dynamic>>(_options);
|
||||
late ProfileModel _value;
|
||||
try {
|
||||
@@ -77,16 +93,22 @@ class _ProfileService implements ProfileService {
|
||||
final queryParameters = <String, dynamic>{};
|
||||
final _headers = <String, dynamic>{};
|
||||
const Map<String, dynamic>? _data = null;
|
||||
final _options = _setStreamType<ProfileDetailsModel>(
|
||||
Options(method: 'GET', headers: _headers, extra: _extra)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/profile/detailz',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(baseUrl: _combineBaseUrls(_dio.options.baseUrl, baseUrl)),
|
||||
);
|
||||
final _options = _setStreamType<ProfileDetailsModel>(Options(
|
||||
method: 'GET',
|
||||
headers: _headers,
|
||||
extra: _extra,
|
||||
)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/profile/detailz',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(
|
||||
baseUrl: _combineBaseUrls(
|
||||
_dio.options.baseUrl,
|
||||
baseUrl,
|
||||
)));
|
||||
final _result = await _dio.fetch<Map<String, dynamic>>(_options);
|
||||
late ProfileDetailsModel _value;
|
||||
try {
|
||||
@@ -99,23 +121,28 @@ class _ProfileService implements ProfileService {
|
||||
}
|
||||
|
||||
@override
|
||||
Future<ProfileDetailsModel> getProfileDetailsBySlug({
|
||||
required String slug,
|
||||
}) async {
|
||||
Future<ProfileDetailsModel> getProfileDetailsBySlug(
|
||||
{required String slug}) async {
|
||||
final _extra = <String, dynamic>{};
|
||||
final queryParameters = <String, dynamic>{};
|
||||
final _headers = <String, dynamic>{};
|
||||
const Map<String, dynamic>? _data = null;
|
||||
final _options = _setStreamType<ProfileDetailsModel>(
|
||||
Options(method: 'GET', headers: _headers, extra: _extra)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/profile/detailz/${slug}',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(baseUrl: _combineBaseUrls(_dio.options.baseUrl, baseUrl)),
|
||||
);
|
||||
final _options = _setStreamType<ProfileDetailsModel>(Options(
|
||||
method: 'GET',
|
||||
headers: _headers,
|
||||
extra: _extra,
|
||||
)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/profile/detailz/${slug}',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(
|
||||
baseUrl: _combineBaseUrls(
|
||||
_dio.options.baseUrl,
|
||||
baseUrl,
|
||||
)));
|
||||
final _result = await _dio.fetch<Map<String, dynamic>>(_options);
|
||||
late ProfileDetailsModel _value;
|
||||
try {
|
||||
@@ -137,25 +164,34 @@ class _ProfileService implements ProfileService {
|
||||
final queryParameters = <String, dynamic>{};
|
||||
final _headers = <String, dynamic>{};
|
||||
final _data = FormData();
|
||||
_data.fields.add(
|
||||
MapEntry('chest_circumference', chestCircumference.toString()),
|
||||
);
|
||||
_data.fields.add(
|
||||
MapEntry('waist_circumference', waistCircumference.toString()),
|
||||
);
|
||||
_data.fields.add(
|
||||
MapEntry('hip_circumference', hipCircumference.toString()),
|
||||
);
|
||||
final _options = _setStreamType<void>(
|
||||
Options(method: 'POST', headers: _headers, extra: _extra)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/profile/addCircumference',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(baseUrl: _combineBaseUrls(_dio.options.baseUrl, baseUrl)),
|
||||
);
|
||||
_data.fields.add(MapEntry(
|
||||
'chest_circumference',
|
||||
chestCircumference.toString(),
|
||||
));
|
||||
_data.fields.add(MapEntry(
|
||||
'waist_circumference',
|
||||
waistCircumference.toString(),
|
||||
));
|
||||
_data.fields.add(MapEntry(
|
||||
'hip_circumference',
|
||||
hipCircumference.toString(),
|
||||
));
|
||||
final _options = _setStreamType<void>(Options(
|
||||
method: 'POST',
|
||||
headers: _headers,
|
||||
extra: _extra,
|
||||
)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/profile/addCircumference',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(
|
||||
baseUrl: _combineBaseUrls(
|
||||
_dio.options.baseUrl,
|
||||
baseUrl,
|
||||
)));
|
||||
await _dio.fetch<void>(_options);
|
||||
}
|
||||
|
||||
@@ -165,46 +201,58 @@ class _ProfileService implements ProfileService {
|
||||
final queryParameters = <String, dynamic>{};
|
||||
final _headers = <String, dynamic>{};
|
||||
final _data = FormData();
|
||||
_data.fields.add(MapEntry('weight', weight.toString()));
|
||||
final _options = _setStreamType<void>(
|
||||
Options(method: 'POST', headers: _headers, extra: _extra)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/profile/addWeight',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(baseUrl: _combineBaseUrls(_dio.options.baseUrl, baseUrl)),
|
||||
);
|
||||
_data.fields.add(MapEntry(
|
||||
'weight',
|
||||
weight.toString(),
|
||||
));
|
||||
final _options = _setStreamType<void>(Options(
|
||||
method: 'POST',
|
||||
headers: _headers,
|
||||
extra: _extra,
|
||||
)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/profile/addWeight',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(
|
||||
baseUrl: _combineBaseUrls(
|
||||
_dio.options.baseUrl,
|
||||
baseUrl,
|
||||
)));
|
||||
await _dio.fetch<void>(_options);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<List<FeedBlogPostModel>> getBlogPostByAuthorSlug({
|
||||
required String slug,
|
||||
}) async {
|
||||
Future<List<FeedBlogPostModel>> getBlogPostByAuthorSlug(
|
||||
{required String slug}) async {
|
||||
final _extra = <String, dynamic>{};
|
||||
final queryParameters = <String, dynamic>{};
|
||||
final _headers = <String, dynamic>{};
|
||||
const Map<String, dynamic>? _data = null;
|
||||
final _options = _setStreamType<List<FeedBlogPostModel>>(
|
||||
Options(method: 'GET', headers: _headers, extra: _extra)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/blogPosts/search_by_author/${slug}',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(baseUrl: _combineBaseUrls(_dio.options.baseUrl, baseUrl)),
|
||||
);
|
||||
final _options = _setStreamType<List<FeedBlogPostModel>>(Options(
|
||||
method: 'GET',
|
||||
headers: _headers,
|
||||
extra: _extra,
|
||||
)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/blogPosts/search_by_author/${slug}',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(
|
||||
baseUrl: _combineBaseUrls(
|
||||
_dio.options.baseUrl,
|
||||
baseUrl,
|
||||
)));
|
||||
final _result = await _dio.fetch<List<dynamic>>(_options);
|
||||
late List<FeedBlogPostModel> _value;
|
||||
try {
|
||||
_value = _result.data!
|
||||
.map(
|
||||
(dynamic i) =>
|
||||
FeedBlogPostModel.fromJson(i as Map<String, dynamic>),
|
||||
)
|
||||
.map((dynamic i) =>
|
||||
FeedBlogPostModel.fromJson(i as Map<String, dynamic>))
|
||||
.toList();
|
||||
} on Object catch (e, s) {
|
||||
errorLogger?.logError(e, s, _options);
|
||||
@@ -219,23 +267,27 @@ class _ProfileService implements ProfileService {
|
||||
final queryParameters = <String, dynamic>{};
|
||||
final _headers = <String, dynamic>{};
|
||||
const Map<String, dynamic>? _data = null;
|
||||
final _options = _setStreamType<List<WeightModel>>(
|
||||
Options(method: 'GET', headers: _headers, extra: _extra)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/profile/measure/weight/${period}',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(baseUrl: _combineBaseUrls(_dio.options.baseUrl, baseUrl)),
|
||||
);
|
||||
final _options = _setStreamType<List<WeightModel>>(Options(
|
||||
method: 'GET',
|
||||
headers: _headers,
|
||||
extra: _extra,
|
||||
)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/profile/measure/weight/${period}',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(
|
||||
baseUrl: _combineBaseUrls(
|
||||
_dio.options.baseUrl,
|
||||
baseUrl,
|
||||
)));
|
||||
final _result = await _dio.fetch<List<dynamic>>(_options);
|
||||
late List<WeightModel> _value;
|
||||
try {
|
||||
_value = _result.data!
|
||||
.map(
|
||||
(dynamic i) => WeightModel.fromJson(i as Map<String, dynamic>),
|
||||
)
|
||||
.map((dynamic i) => WeightModel.fromJson(i as Map<String, dynamic>))
|
||||
.toList();
|
||||
} on Object catch (e, s) {
|
||||
errorLogger?.logError(e, s, _options);
|
||||
@@ -253,23 +305,27 @@ class _ProfileService implements ProfileService {
|
||||
final queryParameters = <String, dynamic>{};
|
||||
final _headers = <String, dynamic>{};
|
||||
const Map<String, dynamic>? _data = null;
|
||||
final _options = _setStreamType<List<WeightModel>>(
|
||||
Options(method: 'GET', headers: _headers, extra: _extra)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/profile/measure/weight/${period}/${slug}',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(baseUrl: _combineBaseUrls(_dio.options.baseUrl, baseUrl)),
|
||||
);
|
||||
final _options = _setStreamType<List<WeightModel>>(Options(
|
||||
method: 'GET',
|
||||
headers: _headers,
|
||||
extra: _extra,
|
||||
)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/profile/measure/weight/${period}/${slug}',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(
|
||||
baseUrl: _combineBaseUrls(
|
||||
_dio.options.baseUrl,
|
||||
baseUrl,
|
||||
)));
|
||||
final _result = await _dio.fetch<List<dynamic>>(_options);
|
||||
late List<WeightModel> _value;
|
||||
try {
|
||||
_value = _result.data!
|
||||
.map(
|
||||
(dynamic i) => WeightModel.fromJson(i as Map<String, dynamic>),
|
||||
)
|
||||
.map((dynamic i) => WeightModel.fromJson(i as Map<String, dynamic>))
|
||||
.toList();
|
||||
} on Object catch (e, s) {
|
||||
errorLogger?.logError(e, s, _options);
|
||||
@@ -279,31 +335,34 @@ class _ProfileService implements ProfileService {
|
||||
}
|
||||
|
||||
@override
|
||||
Future<List<CircumferenceModel>> getCircumferences({
|
||||
required String period,
|
||||
}) async {
|
||||
Future<List<CircumferenceModel>> getCircumferences(
|
||||
{required String period}) async {
|
||||
final _extra = <String, dynamic>{};
|
||||
final queryParameters = <String, dynamic>{};
|
||||
final _headers = <String, dynamic>{};
|
||||
const Map<String, dynamic>? _data = null;
|
||||
final _options = _setStreamType<List<CircumferenceModel>>(
|
||||
Options(method: 'GET', headers: _headers, extra: _extra)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/profile/measure/circumferences/${period}',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(baseUrl: _combineBaseUrls(_dio.options.baseUrl, baseUrl)),
|
||||
);
|
||||
final _options = _setStreamType<List<CircumferenceModel>>(Options(
|
||||
method: 'GET',
|
||||
headers: _headers,
|
||||
extra: _extra,
|
||||
)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/profile/measure/circumferences/${period}',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(
|
||||
baseUrl: _combineBaseUrls(
|
||||
_dio.options.baseUrl,
|
||||
baseUrl,
|
||||
)));
|
||||
final _result = await _dio.fetch<List<dynamic>>(_options);
|
||||
late List<CircumferenceModel> _value;
|
||||
try {
|
||||
_value = _result.data!
|
||||
.map(
|
||||
(dynamic i) =>
|
||||
CircumferenceModel.fromJson(i as Map<String, dynamic>),
|
||||
)
|
||||
.map((dynamic i) =>
|
||||
CircumferenceModel.fromJson(i as Map<String, dynamic>))
|
||||
.toList();
|
||||
} on Object catch (e, s) {
|
||||
errorLogger?.logError(e, s, _options);
|
||||
@@ -321,24 +380,28 @@ class _ProfileService implements ProfileService {
|
||||
final queryParameters = <String, dynamic>{};
|
||||
final _headers = <String, dynamic>{};
|
||||
const Map<String, dynamic>? _data = null;
|
||||
final _options = _setStreamType<List<CircumferenceModel>>(
|
||||
Options(method: 'GET', headers: _headers, extra: _extra)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/profile/measure/circumferences/${period}/{user}',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(baseUrl: _combineBaseUrls(_dio.options.baseUrl, baseUrl)),
|
||||
);
|
||||
final _options = _setStreamType<List<CircumferenceModel>>(Options(
|
||||
method: 'GET',
|
||||
headers: _headers,
|
||||
extra: _extra,
|
||||
)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/profile/measure/circumferences/${period}/{user}',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(
|
||||
baseUrl: _combineBaseUrls(
|
||||
_dio.options.baseUrl,
|
||||
baseUrl,
|
||||
)));
|
||||
final _result = await _dio.fetch<List<dynamic>>(_options);
|
||||
late List<CircumferenceModel> _value;
|
||||
try {
|
||||
_value = _result.data!
|
||||
.map(
|
||||
(dynamic i) =>
|
||||
CircumferenceModel.fromJson(i as Map<String, dynamic>),
|
||||
)
|
||||
.map((dynamic i) =>
|
||||
CircumferenceModel.fromJson(i as Map<String, dynamic>))
|
||||
.toList();
|
||||
} on Object catch (e, s) {
|
||||
errorLogger?.logError(e, s, _options);
|
||||
@@ -354,21 +417,27 @@ class _ProfileService implements ProfileService {
|
||||
}) async {
|
||||
final _extra = <String, dynamic>{};
|
||||
final queryParameters = <String, dynamic>{
|
||||
r'filters[name][$startsWith]': query,
|
||||
r'filters[name][$startsWith]': query
|
||||
};
|
||||
queryParameters.removeWhere((k, v) => v == null);
|
||||
final _headers = <String, dynamic>{};
|
||||
const Map<String, dynamic>? _data = null;
|
||||
final _options = _setStreamType<SubPaginationModel>(
|
||||
Options(method: 'GET', headers: _headers, extra: _extra)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/profile/${slug}/subscribers',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(baseUrl: _combineBaseUrls(_dio.options.baseUrl, baseUrl)),
|
||||
);
|
||||
final _options = _setStreamType<SubPaginationModel>(Options(
|
||||
method: 'GET',
|
||||
headers: _headers,
|
||||
extra: _extra,
|
||||
)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/profile/${slug}/subscribers',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(
|
||||
baseUrl: _combineBaseUrls(
|
||||
_dio.options.baseUrl,
|
||||
baseUrl,
|
||||
)));
|
||||
final _result = await _dio.fetch<Map<String, dynamic>>(_options);
|
||||
late SubPaginationModel _value;
|
||||
try {
|
||||
@@ -387,21 +456,27 @@ class _ProfileService implements ProfileService {
|
||||
}) async {
|
||||
final _extra = <String, dynamic>{};
|
||||
final queryParameters = <String, dynamic>{
|
||||
r'filters[name][$startsWith]': query,
|
||||
r'filters[name][$startsWith]': query
|
||||
};
|
||||
queryParameters.removeWhere((k, v) => v == null);
|
||||
final _headers = <String, dynamic>{};
|
||||
const Map<String, dynamic>? _data = null;
|
||||
final _options = _setStreamType<SubPaginationModel>(
|
||||
Options(method: 'GET', headers: _headers, extra: _extra)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/profile/${slug}/subscriptions',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(baseUrl: _combineBaseUrls(_dio.options.baseUrl, baseUrl)),
|
||||
);
|
||||
final _options = _setStreamType<SubPaginationModel>(Options(
|
||||
method: 'GET',
|
||||
headers: _headers,
|
||||
extra: _extra,
|
||||
)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/profile/${slug}/subscriptions',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(
|
||||
baseUrl: _combineBaseUrls(
|
||||
_dio.options.baseUrl,
|
||||
baseUrl,
|
||||
)));
|
||||
final _result = await _dio.fetch<Map<String, dynamic>>(_options);
|
||||
late SubPaginationModel _value;
|
||||
try {
|
||||
@@ -419,16 +494,22 @@ class _ProfileService implements ProfileService {
|
||||
final queryParameters = <String, dynamic>{};
|
||||
final _headers = <String, dynamic>{};
|
||||
const Map<String, dynamic>? _data = null;
|
||||
final _options = _setStreamType<void>(
|
||||
Options(method: 'POST', headers: _headers, extra: _extra)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/profile/subscribe/${slug}',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(baseUrl: _combineBaseUrls(_dio.options.baseUrl, baseUrl)),
|
||||
);
|
||||
final _options = _setStreamType<void>(Options(
|
||||
method: 'POST',
|
||||
headers: _headers,
|
||||
extra: _extra,
|
||||
)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/profile/subscribe/${slug}',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(
|
||||
baseUrl: _combineBaseUrls(
|
||||
_dio.options.baseUrl,
|
||||
baseUrl,
|
||||
)));
|
||||
await _dio.fetch<void>(_options);
|
||||
}
|
||||
|
||||
@@ -438,16 +519,22 @@ class _ProfileService implements ProfileService {
|
||||
final queryParameters = <String, dynamic>{};
|
||||
final _headers = <String, dynamic>{};
|
||||
const Map<String, dynamic>? _data = null;
|
||||
final _options = _setStreamType<void>(
|
||||
Options(method: 'POST', headers: _headers, extra: _extra)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/profile/unsubscribe/${slug}',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(baseUrl: _combineBaseUrls(_dio.options.baseUrl, baseUrl)),
|
||||
);
|
||||
final _options = _setStreamType<void>(Options(
|
||||
method: 'POST',
|
||||
headers: _headers,
|
||||
extra: _extra,
|
||||
)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/profile/unsubscribe/${slug}',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(
|
||||
baseUrl: _combineBaseUrls(
|
||||
_dio.options.baseUrl,
|
||||
baseUrl,
|
||||
)));
|
||||
await _dio.fetch<void>(_options);
|
||||
}
|
||||
|
||||
@@ -457,30 +544,30 @@ class _ProfileService implements ProfileService {
|
||||
final queryParameters = <String, dynamic>{};
|
||||
final _headers = <String, dynamic>{};
|
||||
final _data = FormData();
|
||||
_data.files.add(
|
||||
MapEntry(
|
||||
'photo',
|
||||
MultipartFile.fromFileSync(
|
||||
photo.path,
|
||||
filename: photo.path.split(Platform.pathSeparator).last,
|
||||
),
|
||||
_data.files.add(MapEntry(
|
||||
'photo',
|
||||
MultipartFile.fromFileSync(
|
||||
photo.path,
|
||||
filename: photo.path.split(Platform.pathSeparator).last,
|
||||
),
|
||||
);
|
||||
final _options = _setStreamType<void>(
|
||||
Options(
|
||||
method: 'POST',
|
||||
headers: _headers,
|
||||
extra: _extra,
|
||||
contentType: 'multipart/form-data',
|
||||
)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/profile/photo/upload',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(baseUrl: _combineBaseUrls(_dio.options.baseUrl, baseUrl)),
|
||||
);
|
||||
));
|
||||
final _options = _setStreamType<void>(Options(
|
||||
method: 'POST',
|
||||
headers: _headers,
|
||||
extra: _extra,
|
||||
contentType: 'multipart/form-data',
|
||||
)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/profile/photo/upload',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(
|
||||
baseUrl: _combineBaseUrls(
|
||||
_dio.options.baseUrl,
|
||||
baseUrl,
|
||||
)));
|
||||
await _dio.fetch<void>(_options);
|
||||
}
|
||||
|
||||
@@ -490,19 +577,58 @@ class _ProfileService implements ProfileService {
|
||||
final queryParameters = <String, dynamic>{};
|
||||
final _headers = <String, dynamic>{};
|
||||
const Map<String, dynamic>? _data = null;
|
||||
final _options = _setStreamType<void>(
|
||||
Options(method: 'DELETE', headers: _headers, extra: _extra)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/profile/photo/delete',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(baseUrl: _combineBaseUrls(_dio.options.baseUrl, baseUrl)),
|
||||
);
|
||||
final _options = _setStreamType<void>(Options(
|
||||
method: 'DELETE',
|
||||
headers: _headers,
|
||||
extra: _extra,
|
||||
)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/profile/photo/delete',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(
|
||||
baseUrl: _combineBaseUrls(
|
||||
_dio.options.baseUrl,
|
||||
baseUrl,
|
||||
)));
|
||||
await _dio.fetch<void>(_options);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<ChosenDietsPaginationModel> getChosenDiets() async {
|
||||
final _extra = <String, dynamic>{};
|
||||
final queryParameters = <String, dynamic>{};
|
||||
final _headers = <String, dynamic>{};
|
||||
const Map<String, dynamic>? _data = null;
|
||||
final _options = _setStreamType<ChosenDietsPaginationModel>(Options(
|
||||
method: 'GET',
|
||||
headers: _headers,
|
||||
extra: _extra,
|
||||
)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/profile/chosen_diets',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(
|
||||
baseUrl: _combineBaseUrls(
|
||||
_dio.options.baseUrl,
|
||||
baseUrl,
|
||||
)));
|
||||
final _result = await _dio.fetch<Map<String, dynamic>>(_options);
|
||||
late ChosenDietsPaginationModel _value;
|
||||
try {
|
||||
_value = ChosenDietsPaginationModel.fromJson(_result.data!);
|
||||
} on Object catch (e, s) {
|
||||
errorLogger?.logError(e, s, _options);
|
||||
rethrow;
|
||||
}
|
||||
return _value;
|
||||
}
|
||||
|
||||
RequestOptions _setStreamType<T>(RequestOptions requestOptions) {
|
||||
if (T != dynamic &&
|
||||
!(requestOptions.responseType == ResponseType.bytes ||
|
||||
@@ -516,7 +642,10 @@ class _ProfileService implements ProfileService {
|
||||
return requestOptions;
|
||||
}
|
||||
|
||||
String _combineBaseUrls(String dioBaseUrl, String? baseUrl) {
|
||||
String _combineBaseUrls(
|
||||
String dioBaseUrl,
|
||||
String? baseUrl,
|
||||
) {
|
||||
if (baseUrl == null || baseUrl.trim().isEmpty) {
|
||||
return dioBaseUrl;
|
||||
}
|
||||
|
||||
@@ -9,7 +9,11 @@ part of 'recipe_service.dart';
|
||||
// ignore_for_file: unnecessary_brace_in_string_interps,no_leading_underscores_for_local_identifiers,unused_element,unnecessary_string_interpolations
|
||||
|
||||
class _RecipeService implements RecipeService {
|
||||
_RecipeService(this._dio, {this.baseUrl, this.errorLogger});
|
||||
_RecipeService(
|
||||
this._dio, {
|
||||
this.baseUrl,
|
||||
this.errorLogger,
|
||||
});
|
||||
|
||||
final Dio _dio;
|
||||
|
||||
@@ -23,16 +27,22 @@ class _RecipeService implements RecipeService {
|
||||
final queryParameters = <String, dynamic>{};
|
||||
final _headers = <String, dynamic>{};
|
||||
const Map<String, dynamic>? _data = null;
|
||||
final _options = _setStreamType<RecipeModel>(
|
||||
Options(method: 'GET', headers: _headers, extra: _extra)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/recipes/show/${id}',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(baseUrl: _combineBaseUrls(_dio.options.baseUrl, baseUrl)),
|
||||
);
|
||||
final _options = _setStreamType<RecipeModel>(Options(
|
||||
method: 'GET',
|
||||
headers: _headers,
|
||||
extra: _extra,
|
||||
)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/recipes/show/${id}',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(
|
||||
baseUrl: _combineBaseUrls(
|
||||
_dio.options.baseUrl,
|
||||
baseUrl,
|
||||
)));
|
||||
final _result = await _dio.fetch<Map<String, dynamic>>(_options);
|
||||
late RecipeModel _value;
|
||||
try {
|
||||
@@ -50,27 +60,30 @@ class _RecipeService implements RecipeService {
|
||||
final queryParameters = <String, dynamic>{r'name': name};
|
||||
final _headers = <String, dynamic>{};
|
||||
const Map<String, dynamic>? _data = null;
|
||||
final _options = _setStreamType<Map<String, List<Product>>>(
|
||||
Options(method: 'GET', headers: _headers, extra: _extra)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/diary/product_nutritional_values/filter',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(baseUrl: _combineBaseUrls(_dio.options.baseUrl, baseUrl)),
|
||||
);
|
||||
final _options = _setStreamType<Map<String, List<Product>>>(Options(
|
||||
method: 'GET',
|
||||
headers: _headers,
|
||||
extra: _extra,
|
||||
)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/diary/product_nutritional_values/filter',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(
|
||||
baseUrl: _combineBaseUrls(
|
||||
_dio.options.baseUrl,
|
||||
baseUrl,
|
||||
)));
|
||||
final _result = await _dio.fetch<Map<String, dynamic>>(_options);
|
||||
late Map<String, List<Product>> _value;
|
||||
try {
|
||||
_value = _result.data!.map(
|
||||
(k, dynamic v) => MapEntry(
|
||||
_value = _result.data!.map((k, dynamic v) => MapEntry(
|
||||
k,
|
||||
(v as List)
|
||||
.map((i) => Product.fromJson(i as Map<String, dynamic>))
|
||||
.toList(),
|
||||
),
|
||||
);
|
||||
.toList()));
|
||||
} on Object catch (e, s) {
|
||||
errorLogger?.logError(e, s, _options);
|
||||
rethrow;
|
||||
@@ -96,19 +109,34 @@ class _RecipeService implements RecipeService {
|
||||
final _headers = <String, dynamic>{};
|
||||
final _data = FormData();
|
||||
if (type != null) {
|
||||
_data.fields.add(MapEntry('type', type));
|
||||
_data.fields.add(MapEntry(
|
||||
'type',
|
||||
type,
|
||||
));
|
||||
}
|
||||
if (state != null) {
|
||||
_data.fields.add(MapEntry('state', state));
|
||||
_data.fields.add(MapEntry(
|
||||
'state',
|
||||
state,
|
||||
));
|
||||
}
|
||||
if (title != null) {
|
||||
_data.fields.add(MapEntry('title', title));
|
||||
_data.fields.add(MapEntry(
|
||||
'title',
|
||||
title,
|
||||
));
|
||||
}
|
||||
if (description != null) {
|
||||
_data.fields.add(MapEntry('description', description));
|
||||
_data.fields.add(MapEntry(
|
||||
'description',
|
||||
description,
|
||||
));
|
||||
}
|
||||
if (video_url != null) {
|
||||
_data.fields.add(MapEntry('video_url', video_url));
|
||||
_data.fields.add(MapEntry(
|
||||
'video_url',
|
||||
video_url,
|
||||
));
|
||||
}
|
||||
ingredients.forEach((i) {
|
||||
_data.fields.add(MapEntry('ingredients', jsonEncode(i)));
|
||||
@@ -117,27 +145,34 @@ class _RecipeService implements RecipeService {
|
||||
_data.fields.add(MapEntry('steps', jsonEncode(i)));
|
||||
});
|
||||
if (cooking_time != null) {
|
||||
_data.fields.add(MapEntry('cooking_time', cooking_time.toString()));
|
||||
_data.fields.add(MapEntry(
|
||||
'cooking_time',
|
||||
cooking_time.toString(),
|
||||
));
|
||||
}
|
||||
_data.files.add(
|
||||
MapEntry(
|
||||
'image',
|
||||
MultipartFile.fromFileSync(
|
||||
image.path,
|
||||
filename: image.path.split(Platform.pathSeparator).last,
|
||||
),
|
||||
_data.files.add(MapEntry(
|
||||
'image',
|
||||
MultipartFile.fromFileSync(
|
||||
image.path,
|
||||
filename: image.path.split(Platform.pathSeparator).last,
|
||||
),
|
||||
);
|
||||
final _options = _setStreamType<RecipeModel>(
|
||||
Options(method: 'POST', headers: _headers, extra: _extra)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/recipes/create',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(baseUrl: _combineBaseUrls(_dio.options.baseUrl, baseUrl)),
|
||||
);
|
||||
));
|
||||
final _options = _setStreamType<RecipeModel>(Options(
|
||||
method: 'POST',
|
||||
headers: _headers,
|
||||
extra: _extra,
|
||||
)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/recipes/create',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(
|
||||
baseUrl: _combineBaseUrls(
|
||||
_dio.options.baseUrl,
|
||||
baseUrl,
|
||||
)));
|
||||
final _result = await _dio.fetch<Map<String, dynamic>>(_options);
|
||||
late RecipeModel _value;
|
||||
try {
|
||||
@@ -150,21 +185,30 @@ class _RecipeService implements RecipeService {
|
||||
}
|
||||
|
||||
@override
|
||||
Future<RecipeModel> editRecipe(Map<String, Object?> recipe, String id) async {
|
||||
Future<RecipeModel> editRecipe(
|
||||
Map<String, Object?> recipe,
|
||||
String id,
|
||||
) async {
|
||||
final _extra = <String, dynamic>{};
|
||||
final queryParameters = <String, dynamic>{};
|
||||
final _headers = <String, dynamic>{};
|
||||
final _data = FormData.fromMap(recipe);
|
||||
final _options = _setStreamType<RecipeModel>(
|
||||
Options(method: 'POST', headers: _headers, extra: _extra)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/recipes/update/{id}',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(baseUrl: _combineBaseUrls(_dio.options.baseUrl, baseUrl)),
|
||||
);
|
||||
final _options = _setStreamType<RecipeModel>(Options(
|
||||
method: 'POST',
|
||||
headers: _headers,
|
||||
extra: _extra,
|
||||
)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/recipes/update/{id}',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(
|
||||
baseUrl: _combineBaseUrls(
|
||||
_dio.options.baseUrl,
|
||||
baseUrl,
|
||||
)));
|
||||
final _result = await _dio.fetch<Map<String, dynamic>>(_options);
|
||||
late RecipeModel _value;
|
||||
try {
|
||||
@@ -182,16 +226,22 @@ class _RecipeService implements RecipeService {
|
||||
final queryParameters = <String, dynamic>{};
|
||||
final _headers = <String, dynamic>{};
|
||||
const Map<String, dynamic>? _data = null;
|
||||
final _options = _setStreamType<RecipeTagModel>(
|
||||
Options(method: 'GET', headers: _headers, extra: _extra)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/recipes/tags',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(baseUrl: _combineBaseUrls(_dio.options.baseUrl, baseUrl)),
|
||||
);
|
||||
final _options = _setStreamType<RecipeTagModel>(Options(
|
||||
method: 'GET',
|
||||
headers: _headers,
|
||||
extra: _extra,
|
||||
)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/recipes/tags',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(
|
||||
baseUrl: _combineBaseUrls(
|
||||
_dio.options.baseUrl,
|
||||
baseUrl,
|
||||
)));
|
||||
final _result = await _dio.fetch<Map<String, dynamic>>(_options);
|
||||
late RecipeTagModel _value;
|
||||
try {
|
||||
@@ -216,7 +266,10 @@ class _RecipeService implements RecipeService {
|
||||
return requestOptions;
|
||||
}
|
||||
|
||||
String _combineBaseUrls(String dioBaseUrl, String? baseUrl) {
|
||||
String _combineBaseUrls(
|
||||
String dioBaseUrl,
|
||||
String? baseUrl,
|
||||
) {
|
||||
if (baseUrl == null || baseUrl.trim().isEmpty) {
|
||||
return dioBaseUrl;
|
||||
}
|
||||
|
||||
@@ -9,7 +9,11 @@ part of 'registration_service.dart';
|
||||
// ignore_for_file: unnecessary_brace_in_string_interps,no_leading_underscores_for_local_identifiers,unused_element,unnecessary_string_interpolations
|
||||
|
||||
class _RegistrationService implements RegistrationService {
|
||||
_RegistrationService(this._dio, {this.baseUrl, this.errorLogger});
|
||||
_RegistrationService(
|
||||
this._dio, {
|
||||
this.baseUrl,
|
||||
this.errorLogger,
|
||||
});
|
||||
|
||||
final Dio _dio;
|
||||
|
||||
@@ -18,24 +22,29 @@ class _RegistrationService implements RegistrationService {
|
||||
final ParseErrorLogger? errorLogger;
|
||||
|
||||
@override
|
||||
Future<Map<String, String>> register({
|
||||
required Map<String, dynamic> sheet,
|
||||
}) async {
|
||||
Future<Map<String, String>> register(
|
||||
{required Map<String, dynamic> sheet}) async {
|
||||
final _extra = <String, dynamic>{};
|
||||
final queryParameters = <String, dynamic>{};
|
||||
final _headers = <String, dynamic>{};
|
||||
final _data = <String, dynamic>{};
|
||||
_data.addAll(sheet);
|
||||
final _options = _setStreamType<Map<String, String>>(
|
||||
Options(method: 'POST', headers: _headers, extra: _extra)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/register',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(baseUrl: _combineBaseUrls(_dio.options.baseUrl, baseUrl)),
|
||||
);
|
||||
final _options = _setStreamType<Map<String, String>>(Options(
|
||||
method: 'POST',
|
||||
headers: _headers,
|
||||
extra: _extra,
|
||||
)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/register',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(
|
||||
baseUrl: _combineBaseUrls(
|
||||
_dio.options.baseUrl,
|
||||
baseUrl,
|
||||
)));
|
||||
final _result = await _dio.fetch<Map<String, dynamic>>(_options);
|
||||
late Map<String, String> _value;
|
||||
try {
|
||||
@@ -53,16 +62,22 @@ class _RegistrationService implements RegistrationService {
|
||||
final queryParameters = <String, dynamic>{r'user_address': query};
|
||||
final _headers = <String, dynamic>{};
|
||||
const Map<String, dynamic>? _data = null;
|
||||
final _options = _setStreamType<LocationModel>(
|
||||
Options(method: 'GET', headers: _headers, extra: _extra)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/location_by_address',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(baseUrl: _combineBaseUrls(_dio.options.baseUrl, baseUrl)),
|
||||
);
|
||||
final _options = _setStreamType<LocationModel>(Options(
|
||||
method: 'GET',
|
||||
headers: _headers,
|
||||
extra: _extra,
|
||||
)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/location_by_address',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(
|
||||
baseUrl: _combineBaseUrls(
|
||||
_dio.options.baseUrl,
|
||||
baseUrl,
|
||||
)));
|
||||
final _result = await _dio.fetch<Map<String, dynamic>>(_options);
|
||||
late LocationModel _value;
|
||||
try {
|
||||
@@ -86,16 +101,22 @@ class _RegistrationService implements RegistrationService {
|
||||
};
|
||||
final _headers = <String, dynamic>{};
|
||||
const Map<String, dynamic>? _data = null;
|
||||
final _options = _setStreamType<LocationModel>(
|
||||
Options(method: 'GET', headers: _headers, extra: _extra)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/location_by_coordinate',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(baseUrl: _combineBaseUrls(_dio.options.baseUrl, baseUrl)),
|
||||
);
|
||||
final _options = _setStreamType<LocationModel>(Options(
|
||||
method: 'GET',
|
||||
headers: _headers,
|
||||
extra: _extra,
|
||||
)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/location_by_coordinate',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(
|
||||
baseUrl: _combineBaseUrls(
|
||||
_dio.options.baseUrl,
|
||||
baseUrl,
|
||||
)));
|
||||
final _result = await _dio.fetch<Map<String, dynamic>>(_options);
|
||||
late LocationModel _value;
|
||||
try {
|
||||
@@ -120,7 +141,10 @@ class _RegistrationService implements RegistrationService {
|
||||
return requestOptions;
|
||||
}
|
||||
|
||||
String _combineBaseUrls(String dioBaseUrl, String? baseUrl) {
|
||||
String _combineBaseUrls(
|
||||
String dioBaseUrl,
|
||||
String? baseUrl,
|
||||
) {
|
||||
if (baseUrl == null || baseUrl.trim().isEmpty) {
|
||||
return dioBaseUrl;
|
||||
}
|
||||
|
||||
@@ -9,7 +9,11 @@ part of 'settings_service.dart';
|
||||
// ignore_for_file: unnecessary_brace_in_string_interps,no_leading_underscores_for_local_identifiers,unused_element,unnecessary_string_interpolations
|
||||
|
||||
class _SettingsService implements SettingsService {
|
||||
_SettingsService(this._dio, {this.baseUrl, this.errorLogger});
|
||||
_SettingsService(
|
||||
this._dio, {
|
||||
this.baseUrl,
|
||||
this.errorLogger,
|
||||
});
|
||||
|
||||
final Dio _dio;
|
||||
|
||||
@@ -23,16 +27,22 @@ class _SettingsService implements SettingsService {
|
||||
final queryParameters = <String, dynamic>{};
|
||||
final _headers = <String, dynamic>{};
|
||||
const Map<String, dynamic>? _data = null;
|
||||
final _options = _setStreamType<ProfileSettingsModel>(
|
||||
Options(method: 'GET', headers: _headers, extra: _extra)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/profile/settings',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(baseUrl: _combineBaseUrls(_dio.options.baseUrl, baseUrl)),
|
||||
);
|
||||
final _options = _setStreamType<ProfileSettingsModel>(Options(
|
||||
method: 'GET',
|
||||
headers: _headers,
|
||||
extra: _extra,
|
||||
)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/profile/settings',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(
|
||||
baseUrl: _combineBaseUrls(
|
||||
_dio.options.baseUrl,
|
||||
baseUrl,
|
||||
)));
|
||||
final _result = await _dio.fetch<Map<String, dynamic>>(_options);
|
||||
late ProfileSettingsModel _value;
|
||||
try {
|
||||
@@ -45,24 +55,29 @@ class _SettingsService implements SettingsService {
|
||||
}
|
||||
|
||||
@override
|
||||
Future<ProfileSettingsModel> updateProfileSettings({
|
||||
required Map<String, dynamic> data,
|
||||
}) async {
|
||||
Future<ProfileSettingsModel> updateProfileSettings(
|
||||
{required Map<String, dynamic> data}) async {
|
||||
final _extra = <String, dynamic>{};
|
||||
final queryParameters = <String, dynamic>{};
|
||||
final _headers = <String, dynamic>{};
|
||||
final _data = <String, dynamic>{};
|
||||
_data.addAll(data);
|
||||
final _options = _setStreamType<ProfileSettingsModel>(
|
||||
Options(method: 'POST', headers: _headers, extra: _extra)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/profile/settings/update',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(baseUrl: _combineBaseUrls(_dio.options.baseUrl, baseUrl)),
|
||||
);
|
||||
final _options = _setStreamType<ProfileSettingsModel>(Options(
|
||||
method: 'POST',
|
||||
headers: _headers,
|
||||
extra: _extra,
|
||||
)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/profile/settings/update',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(
|
||||
baseUrl: _combineBaseUrls(
|
||||
_dio.options.baseUrl,
|
||||
baseUrl,
|
||||
)));
|
||||
final _result = await _dio.fetch<Map<String, dynamic>>(_options);
|
||||
late ProfileSettingsModel _value;
|
||||
try {
|
||||
@@ -75,24 +90,29 @@ class _SettingsService implements SettingsService {
|
||||
}
|
||||
|
||||
@override
|
||||
Future<ProfileDetailsModel> updateProfileDetails({
|
||||
required Map<String, dynamic> data,
|
||||
}) async {
|
||||
Future<ProfileDetailsModel> updateProfileDetails(
|
||||
{required Map<String, dynamic> data}) async {
|
||||
final _extra = <String, dynamic>{};
|
||||
final queryParameters = <String, dynamic>{};
|
||||
final _headers = <String, dynamic>{};
|
||||
final _data = <String, dynamic>{};
|
||||
_data.addAll(data);
|
||||
final _options = _setStreamType<ProfileDetailsModel>(
|
||||
Options(method: 'POST', headers: _headers, extra: _extra)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/profile/update',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(baseUrl: _combineBaseUrls(_dio.options.baseUrl, baseUrl)),
|
||||
);
|
||||
final _options = _setStreamType<ProfileDetailsModel>(Options(
|
||||
method: 'POST',
|
||||
headers: _headers,
|
||||
extra: _extra,
|
||||
)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/profile/update',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
.copyWith(
|
||||
baseUrl: _combineBaseUrls(
|
||||
_dio.options.baseUrl,
|
||||
baseUrl,
|
||||
)));
|
||||
final _result = await _dio.fetch<Map<String, dynamic>>(_options);
|
||||
late ProfileDetailsModel _value;
|
||||
try {
|
||||
@@ -117,7 +137,10 @@ class _SettingsService implements SettingsService {
|
||||
return requestOptions;
|
||||
}
|
||||
|
||||
String _combineBaseUrls(String dioBaseUrl, String? baseUrl) {
|
||||
String _combineBaseUrls(
|
||||
String dioBaseUrl,
|
||||
String? baseUrl,
|
||||
) {
|
||||
if (baseUrl == null || baseUrl.trim().isEmpty) {
|
||||
return dioBaseUrl;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import 'package:eatvio_app/core/app_router.dart';
|
||||
import 'package:eatvio_app/core/initialization_cubit/initialization_cubit.dart';
|
||||
import 'package:eatvio_app/core/locator_service.dart' as di;
|
||||
import 'package:eatvio_app/core/locator_service.dart';
|
||||
import 'package:eatvio_app/core/theme/theme_helper.dart';
|
||||
@@ -27,8 +26,7 @@ class MyApp extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return MultiBlocProvider(
|
||||
providers: [
|
||||
BlocProvider<InitializationCubit>(create: (context) => sl<InitializationCubit>()..runInitialization()),
|
||||
providers: [
|
||||
BlocProvider<NewMessagesCubit>(create: (context) => sl<NewMessagesCubit>()),
|
||||
BlocProvider<NotificationsCubit>(create: (context) => sl<NotificationsCubit>()),
|
||||
BlocProvider<FeedCubit>(create: (context) => sl<FeedCubit>()..loadFeedBlogPostList()),
|
||||
|
||||
@@ -1,20 +1,22 @@
|
||||
// Mocks generated by Mockito 5.4.5 from annotations
|
||||
// Mocks generated by Mockito 5.4.4 from annotations
|
||||
// in eatvio_app/test/features/profile/services/profile_service_test.dart.
|
||||
// Do not manually edit this file.
|
||||
|
||||
// ignore_for_file: no_leading_underscores_for_library_prefixes
|
||||
import 'dart:async' as _i5;
|
||||
import 'dart:io' as _i9;
|
||||
import 'dart:async' as _i6;
|
||||
import 'dart:io' as _i10;
|
||||
|
||||
import 'package:eatvio_app/features/feed/models/feed_blog_post_model.dart'
|
||||
as _i6;
|
||||
as _i7;
|
||||
import 'package:eatvio_app/features/profile/models/chosen_diets_pagination_model.dart'
|
||||
as _i4;
|
||||
import 'package:eatvio_app/features/profile/models/circumference_model.dart'
|
||||
as _i8;
|
||||
as _i9;
|
||||
import 'package:eatvio_app/features/profile/models/profile_model.dart' as _i2;
|
||||
import 'package:eatvio_app/features/profile/models/sub_model.dart' as _i3;
|
||||
import 'package:eatvio_app/features/profile/models/weight_model.dart' as _i7;
|
||||
import 'package:eatvio_app/features/profile/models/weight_model.dart' as _i8;
|
||||
import 'package:eatvio_app/features/profile/services/profile_service.dart'
|
||||
as _i4;
|
||||
as _i5;
|
||||
import 'package:mockito/mockito.dart' as _i1;
|
||||
|
||||
// ignore_for_file: type=lint
|
||||
@@ -25,314 +27,427 @@ import 'package:mockito/mockito.dart' as _i1;
|
||||
// ignore_for_file: deprecated_member_use_from_same_package
|
||||
// ignore_for_file: implementation_imports
|
||||
// ignore_for_file: invalid_use_of_visible_for_testing_member
|
||||
// ignore_for_file: must_be_immutable
|
||||
// ignore_for_file: prefer_const_constructors
|
||||
// ignore_for_file: unnecessary_parenthesis
|
||||
// ignore_for_file: camel_case_types
|
||||
// ignore_for_file: subtype_of_sealed_class
|
||||
|
||||
class _FakeProfileModel_0 extends _i1.SmartFake implements _i2.ProfileModel {
|
||||
_FakeProfileModel_0(Object parent, Invocation parentInvocation)
|
||||
: super(parent, parentInvocation);
|
||||
_FakeProfileModel_0(
|
||||
Object parent,
|
||||
Invocation parentInvocation,
|
||||
) : super(
|
||||
parent,
|
||||
parentInvocation,
|
||||
);
|
||||
}
|
||||
|
||||
class _FakeProfileDetailsModel_1 extends _i1.SmartFake
|
||||
implements _i2.ProfileDetailsModel {
|
||||
_FakeProfileDetailsModel_1(Object parent, Invocation parentInvocation)
|
||||
: super(parent, parentInvocation);
|
||||
_FakeProfileDetailsModel_1(
|
||||
Object parent,
|
||||
Invocation parentInvocation,
|
||||
) : super(
|
||||
parent,
|
||||
parentInvocation,
|
||||
);
|
||||
}
|
||||
|
||||
class _FakeSubPaginationModel_2 extends _i1.SmartFake
|
||||
implements _i3.SubPaginationModel {
|
||||
_FakeSubPaginationModel_2(Object parent, Invocation parentInvocation)
|
||||
: super(parent, parentInvocation);
|
||||
_FakeSubPaginationModel_2(
|
||||
Object parent,
|
||||
Invocation parentInvocation,
|
||||
) : super(
|
||||
parent,
|
||||
parentInvocation,
|
||||
);
|
||||
}
|
||||
|
||||
class _FakeChosenDietsPaginationModel_3 extends _i1.SmartFake
|
||||
implements _i4.ChosenDietsPaginationModel {
|
||||
_FakeChosenDietsPaginationModel_3(
|
||||
Object parent,
|
||||
Invocation parentInvocation,
|
||||
) : super(
|
||||
parent,
|
||||
parentInvocation,
|
||||
);
|
||||
}
|
||||
|
||||
/// A class which mocks [ProfileService].
|
||||
///
|
||||
/// See the documentation for Mockito's code generation for more information.
|
||||
class MockProfileService extends _i1.Mock implements _i4.ProfileService {
|
||||
class MockProfileService extends _i1.Mock implements _i5.ProfileService {
|
||||
@override
|
||||
_i5.Future<_i2.ProfileModel> getProfileBySlug({required String? slug}) =>
|
||||
_i6.Future<_i2.ProfileModel> getProfileBySlug({required String? slug}) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(#getProfileBySlug, [], {#slug: slug}),
|
||||
returnValue: _i5.Future<_i2.ProfileModel>.value(
|
||||
_FakeProfileModel_0(
|
||||
this,
|
||||
Invocation.method(#getProfileBySlug, [], {#slug: slug}),
|
||||
),
|
||||
),
|
||||
returnValueForMissingStub: _i5.Future<_i2.ProfileModel>.value(
|
||||
_FakeProfileModel_0(
|
||||
this,
|
||||
Invocation.method(#getProfileBySlug, [], {#slug: slug}),
|
||||
),
|
||||
),
|
||||
)
|
||||
as _i5.Future<_i2.ProfileModel>);
|
||||
Invocation.method(
|
||||
#getProfileBySlug,
|
||||
[],
|
||||
{#slug: slug},
|
||||
),
|
||||
returnValue: _i6.Future<_i2.ProfileModel>.value(_FakeProfileModel_0(
|
||||
this,
|
||||
Invocation.method(
|
||||
#getProfileBySlug,
|
||||
[],
|
||||
{#slug: slug},
|
||||
),
|
||||
)),
|
||||
returnValueForMissingStub:
|
||||
_i6.Future<_i2.ProfileModel>.value(_FakeProfileModel_0(
|
||||
this,
|
||||
Invocation.method(
|
||||
#getProfileBySlug,
|
||||
[],
|
||||
{#slug: slug},
|
||||
),
|
||||
)),
|
||||
) as _i6.Future<_i2.ProfileModel>);
|
||||
|
||||
@override
|
||||
_i5.Future<_i2.ProfileModel> getMyProfile() =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(#getMyProfile, []),
|
||||
returnValue: _i5.Future<_i2.ProfileModel>.value(
|
||||
_FakeProfileModel_0(this, Invocation.method(#getMyProfile, [])),
|
||||
),
|
||||
returnValueForMissingStub: _i5.Future<_i2.ProfileModel>.value(
|
||||
_FakeProfileModel_0(this, Invocation.method(#getMyProfile, [])),
|
||||
),
|
||||
)
|
||||
as _i5.Future<_i2.ProfileModel>);
|
||||
_i6.Future<_i2.ProfileModel> getMyProfile() => (super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#getMyProfile,
|
||||
[],
|
||||
),
|
||||
returnValue: _i6.Future<_i2.ProfileModel>.value(_FakeProfileModel_0(
|
||||
this,
|
||||
Invocation.method(
|
||||
#getMyProfile,
|
||||
[],
|
||||
),
|
||||
)),
|
||||
returnValueForMissingStub:
|
||||
_i6.Future<_i2.ProfileModel>.value(_FakeProfileModel_0(
|
||||
this,
|
||||
Invocation.method(
|
||||
#getMyProfile,
|
||||
[],
|
||||
),
|
||||
)),
|
||||
) as _i6.Future<_i2.ProfileModel>);
|
||||
|
||||
@override
|
||||
_i5.Future<_i2.ProfileDetailsModel> getMyProfileDetails() =>
|
||||
_i6.Future<_i2.ProfileDetailsModel> getMyProfileDetails() =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(#getMyProfileDetails, []),
|
||||
returnValue: _i5.Future<_i2.ProfileDetailsModel>.value(
|
||||
_FakeProfileDetailsModel_1(
|
||||
this,
|
||||
Invocation.method(#getMyProfileDetails, []),
|
||||
),
|
||||
),
|
||||
returnValueForMissingStub:
|
||||
_i5.Future<_i2.ProfileDetailsModel>.value(
|
||||
_FakeProfileDetailsModel_1(
|
||||
this,
|
||||
Invocation.method(#getMyProfileDetails, []),
|
||||
),
|
||||
),
|
||||
)
|
||||
as _i5.Future<_i2.ProfileDetailsModel>);
|
||||
Invocation.method(
|
||||
#getMyProfileDetails,
|
||||
[],
|
||||
),
|
||||
returnValue: _i6.Future<_i2.ProfileDetailsModel>.value(
|
||||
_FakeProfileDetailsModel_1(
|
||||
this,
|
||||
Invocation.method(
|
||||
#getMyProfileDetails,
|
||||
[],
|
||||
),
|
||||
)),
|
||||
returnValueForMissingStub: _i6.Future<_i2.ProfileDetailsModel>.value(
|
||||
_FakeProfileDetailsModel_1(
|
||||
this,
|
||||
Invocation.method(
|
||||
#getMyProfileDetails,
|
||||
[],
|
||||
),
|
||||
)),
|
||||
) as _i6.Future<_i2.ProfileDetailsModel>);
|
||||
|
||||
@override
|
||||
_i5.Future<_i2.ProfileDetailsModel> getProfileDetailsBySlug({
|
||||
required String? slug,
|
||||
}) =>
|
||||
_i6.Future<_i2.ProfileDetailsModel> getProfileDetailsBySlug(
|
||||
{required String? slug}) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(#getProfileDetailsBySlug, [], {#slug: slug}),
|
||||
returnValue: _i5.Future<_i2.ProfileDetailsModel>.value(
|
||||
_FakeProfileDetailsModel_1(
|
||||
this,
|
||||
Invocation.method(#getProfileDetailsBySlug, [], {#slug: slug}),
|
||||
),
|
||||
),
|
||||
returnValueForMissingStub:
|
||||
_i5.Future<_i2.ProfileDetailsModel>.value(
|
||||
_FakeProfileDetailsModel_1(
|
||||
this,
|
||||
Invocation.method(#getProfileDetailsBySlug, [], {
|
||||
#slug: slug,
|
||||
}),
|
||||
),
|
||||
),
|
||||
)
|
||||
as _i5.Future<_i2.ProfileDetailsModel>);
|
||||
Invocation.method(
|
||||
#getProfileDetailsBySlug,
|
||||
[],
|
||||
{#slug: slug},
|
||||
),
|
||||
returnValue: _i6.Future<_i2.ProfileDetailsModel>.value(
|
||||
_FakeProfileDetailsModel_1(
|
||||
this,
|
||||
Invocation.method(
|
||||
#getProfileDetailsBySlug,
|
||||
[],
|
||||
{#slug: slug},
|
||||
),
|
||||
)),
|
||||
returnValueForMissingStub: _i6.Future<_i2.ProfileDetailsModel>.value(
|
||||
_FakeProfileDetailsModel_1(
|
||||
this,
|
||||
Invocation.method(
|
||||
#getProfileDetailsBySlug,
|
||||
[],
|
||||
{#slug: slug},
|
||||
),
|
||||
)),
|
||||
) as _i6.Future<_i2.ProfileDetailsModel>);
|
||||
|
||||
@override
|
||||
_i5.Future<void> addCircumference({
|
||||
_i6.Future<void> addCircumference({
|
||||
required int? chestCircumference,
|
||||
required int? waistCircumference,
|
||||
required int? hipCircumference,
|
||||
}) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(#addCircumference, [], {
|
||||
#chestCircumference: chestCircumference,
|
||||
#waistCircumference: waistCircumference,
|
||||
#hipCircumference: hipCircumference,
|
||||
}),
|
||||
returnValue: _i5.Future<void>.value(),
|
||||
returnValueForMissingStub: _i5.Future<void>.value(),
|
||||
)
|
||||
as _i5.Future<void>);
|
||||
Invocation.method(
|
||||
#addCircumference,
|
||||
[],
|
||||
{
|
||||
#chestCircumference: chestCircumference,
|
||||
#waistCircumference: waistCircumference,
|
||||
#hipCircumference: hipCircumference,
|
||||
},
|
||||
),
|
||||
returnValue: _i6.Future<void>.value(),
|
||||
returnValueForMissingStub: _i6.Future<void>.value(),
|
||||
) as _i6.Future<void>);
|
||||
|
||||
@override
|
||||
_i5.Future<void> addWeight({required double? weight}) =>
|
||||
_i6.Future<void> addWeight({required double? weight}) => (super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#addWeight,
|
||||
[],
|
||||
{#weight: weight},
|
||||
),
|
||||
returnValue: _i6.Future<void>.value(),
|
||||
returnValueForMissingStub: _i6.Future<void>.value(),
|
||||
) as _i6.Future<void>);
|
||||
|
||||
@override
|
||||
_i6.Future<List<_i7.FeedBlogPostModel>> getBlogPostByAuthorSlug(
|
||||
{required String? slug}) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(#addWeight, [], {#weight: weight}),
|
||||
returnValue: _i5.Future<void>.value(),
|
||||
returnValueForMissingStub: _i5.Future<void>.value(),
|
||||
)
|
||||
as _i5.Future<void>);
|
||||
Invocation.method(
|
||||
#getBlogPostByAuthorSlug,
|
||||
[],
|
||||
{#slug: slug},
|
||||
),
|
||||
returnValue: _i6.Future<List<_i7.FeedBlogPostModel>>.value(
|
||||
<_i7.FeedBlogPostModel>[]),
|
||||
returnValueForMissingStub:
|
||||
_i6.Future<List<_i7.FeedBlogPostModel>>.value(
|
||||
<_i7.FeedBlogPostModel>[]),
|
||||
) as _i6.Future<List<_i7.FeedBlogPostModel>>);
|
||||
|
||||
@override
|
||||
_i5.Future<List<_i6.FeedBlogPostModel>> getBlogPostByAuthorSlug({
|
||||
required String? slug,
|
||||
}) =>
|
||||
_i6.Future<List<_i8.WeightModel>> getWeight({required String? period}) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(#getBlogPostByAuthorSlug, [], {#slug: slug}),
|
||||
returnValue: _i5.Future<List<_i6.FeedBlogPostModel>>.value(
|
||||
<_i6.FeedBlogPostModel>[],
|
||||
),
|
||||
returnValueForMissingStub:
|
||||
_i5.Future<List<_i6.FeedBlogPostModel>>.value(
|
||||
<_i6.FeedBlogPostModel>[],
|
||||
),
|
||||
)
|
||||
as _i5.Future<List<_i6.FeedBlogPostModel>>);
|
||||
Invocation.method(
|
||||
#getWeight,
|
||||
[],
|
||||
{#period: period},
|
||||
),
|
||||
returnValue:
|
||||
_i6.Future<List<_i8.WeightModel>>.value(<_i8.WeightModel>[]),
|
||||
returnValueForMissingStub:
|
||||
_i6.Future<List<_i8.WeightModel>>.value(<_i8.WeightModel>[]),
|
||||
) as _i6.Future<List<_i8.WeightModel>>);
|
||||
|
||||
@override
|
||||
_i5.Future<List<_i7.WeightModel>> getWeight({required String? period}) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(#getWeight, [], {#period: period}),
|
||||
returnValue: _i5.Future<List<_i7.WeightModel>>.value(
|
||||
<_i7.WeightModel>[],
|
||||
),
|
||||
returnValueForMissingStub: _i5.Future<List<_i7.WeightModel>>.value(
|
||||
<_i7.WeightModel>[],
|
||||
),
|
||||
)
|
||||
as _i5.Future<List<_i7.WeightModel>>);
|
||||
|
||||
@override
|
||||
_i5.Future<List<_i7.WeightModel>> getWeightBySlug({
|
||||
_i6.Future<List<_i8.WeightModel>> getWeightBySlug({
|
||||
required String? period,
|
||||
required String? slug,
|
||||
}) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(#getWeightBySlug, [], {
|
||||
#period: period,
|
||||
#slug: slug,
|
||||
}),
|
||||
returnValue: _i5.Future<List<_i7.WeightModel>>.value(
|
||||
<_i7.WeightModel>[],
|
||||
),
|
||||
returnValueForMissingStub: _i5.Future<List<_i7.WeightModel>>.value(
|
||||
<_i7.WeightModel>[],
|
||||
),
|
||||
)
|
||||
as _i5.Future<List<_i7.WeightModel>>);
|
||||
Invocation.method(
|
||||
#getWeightBySlug,
|
||||
[],
|
||||
{
|
||||
#period: period,
|
||||
#slug: slug,
|
||||
},
|
||||
),
|
||||
returnValue:
|
||||
_i6.Future<List<_i8.WeightModel>>.value(<_i8.WeightModel>[]),
|
||||
returnValueForMissingStub:
|
||||
_i6.Future<List<_i8.WeightModel>>.value(<_i8.WeightModel>[]),
|
||||
) as _i6.Future<List<_i8.WeightModel>>);
|
||||
|
||||
@override
|
||||
_i5.Future<List<_i8.CircumferenceModel>> getCircumferences({
|
||||
required String? period,
|
||||
}) =>
|
||||
_i6.Future<List<_i9.CircumferenceModel>> getCircumferences(
|
||||
{required String? period}) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(#getCircumferences, [], {#period: period}),
|
||||
returnValue: _i5.Future<List<_i8.CircumferenceModel>>.value(
|
||||
<_i8.CircumferenceModel>[],
|
||||
),
|
||||
returnValueForMissingStub:
|
||||
_i5.Future<List<_i8.CircumferenceModel>>.value(
|
||||
<_i8.CircumferenceModel>[],
|
||||
),
|
||||
)
|
||||
as _i5.Future<List<_i8.CircumferenceModel>>);
|
||||
Invocation.method(
|
||||
#getCircumferences,
|
||||
[],
|
||||
{#period: period},
|
||||
),
|
||||
returnValue: _i6.Future<List<_i9.CircumferenceModel>>.value(
|
||||
<_i9.CircumferenceModel>[]),
|
||||
returnValueForMissingStub:
|
||||
_i6.Future<List<_i9.CircumferenceModel>>.value(
|
||||
<_i9.CircumferenceModel>[]),
|
||||
) as _i6.Future<List<_i9.CircumferenceModel>>);
|
||||
|
||||
@override
|
||||
_i5.Future<List<_i8.CircumferenceModel>> getCircumferencesBySlug({
|
||||
_i6.Future<List<_i9.CircumferenceModel>> getCircumferencesBySlug({
|
||||
required String? period,
|
||||
required String? slug,
|
||||
}) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(#getCircumferencesBySlug, [], {
|
||||
#period: period,
|
||||
#slug: slug,
|
||||
}),
|
||||
returnValue: _i5.Future<List<_i8.CircumferenceModel>>.value(
|
||||
<_i8.CircumferenceModel>[],
|
||||
),
|
||||
returnValueForMissingStub:
|
||||
_i5.Future<List<_i8.CircumferenceModel>>.value(
|
||||
<_i8.CircumferenceModel>[],
|
||||
),
|
||||
)
|
||||
as _i5.Future<List<_i8.CircumferenceModel>>);
|
||||
Invocation.method(
|
||||
#getCircumferencesBySlug,
|
||||
[],
|
||||
{
|
||||
#period: period,
|
||||
#slug: slug,
|
||||
},
|
||||
),
|
||||
returnValue: _i6.Future<List<_i9.CircumferenceModel>>.value(
|
||||
<_i9.CircumferenceModel>[]),
|
||||
returnValueForMissingStub:
|
||||
_i6.Future<List<_i9.CircumferenceModel>>.value(
|
||||
<_i9.CircumferenceModel>[]),
|
||||
) as _i6.Future<List<_i9.CircumferenceModel>>);
|
||||
|
||||
@override
|
||||
_i5.Future<_i3.SubPaginationModel> getSubscribers({
|
||||
_i6.Future<_i3.SubPaginationModel> getSubscribers({
|
||||
required String? slug,
|
||||
String? query,
|
||||
}) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(#getSubscribers, [], {
|
||||
Invocation.method(
|
||||
#getSubscribers,
|
||||
[],
|
||||
{
|
||||
#slug: slug,
|
||||
#query: query,
|
||||
},
|
||||
),
|
||||
returnValue:
|
||||
_i6.Future<_i3.SubPaginationModel>.value(_FakeSubPaginationModel_2(
|
||||
this,
|
||||
Invocation.method(
|
||||
#getSubscribers,
|
||||
[],
|
||||
{
|
||||
#slug: slug,
|
||||
#query: query,
|
||||
}),
|
||||
returnValue: _i5.Future<_i3.SubPaginationModel>.value(
|
||||
_FakeSubPaginationModel_2(
|
||||
this,
|
||||
Invocation.method(#getSubscribers, [], {
|
||||
#slug: slug,
|
||||
#query: query,
|
||||
}),
|
||||
),
|
||||
),
|
||||
returnValueForMissingStub: _i5.Future<_i3.SubPaginationModel>.value(
|
||||
_FakeSubPaginationModel_2(
|
||||
this,
|
||||
Invocation.method(#getSubscribers, [], {
|
||||
#slug: slug,
|
||||
#query: query,
|
||||
}),
|
||||
),
|
||||
),
|
||||
)
|
||||
as _i5.Future<_i3.SubPaginationModel>);
|
||||
},
|
||||
),
|
||||
)),
|
||||
returnValueForMissingStub:
|
||||
_i6.Future<_i3.SubPaginationModel>.value(_FakeSubPaginationModel_2(
|
||||
this,
|
||||
Invocation.method(
|
||||
#getSubscribers,
|
||||
[],
|
||||
{
|
||||
#slug: slug,
|
||||
#query: query,
|
||||
},
|
||||
),
|
||||
)),
|
||||
) as _i6.Future<_i3.SubPaginationModel>);
|
||||
|
||||
@override
|
||||
_i5.Future<_i3.SubPaginationModel> getSubscriptions({
|
||||
_i6.Future<_i3.SubPaginationModel> getSubscriptions({
|
||||
required String? slug,
|
||||
String? query,
|
||||
}) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(#getSubscriptions, [], {
|
||||
Invocation.method(
|
||||
#getSubscriptions,
|
||||
[],
|
||||
{
|
||||
#slug: slug,
|
||||
#query: query,
|
||||
},
|
||||
),
|
||||
returnValue:
|
||||
_i6.Future<_i3.SubPaginationModel>.value(_FakeSubPaginationModel_2(
|
||||
this,
|
||||
Invocation.method(
|
||||
#getSubscriptions,
|
||||
[],
|
||||
{
|
||||
#slug: slug,
|
||||
#query: query,
|
||||
}),
|
||||
returnValue: _i5.Future<_i3.SubPaginationModel>.value(
|
||||
_FakeSubPaginationModel_2(
|
||||
this,
|
||||
Invocation.method(#getSubscriptions, [], {
|
||||
#slug: slug,
|
||||
#query: query,
|
||||
}),
|
||||
),
|
||||
),
|
||||
returnValueForMissingStub: _i5.Future<_i3.SubPaginationModel>.value(
|
||||
_FakeSubPaginationModel_2(
|
||||
this,
|
||||
Invocation.method(#getSubscriptions, [], {
|
||||
#slug: slug,
|
||||
#query: query,
|
||||
}),
|
||||
),
|
||||
),
|
||||
)
|
||||
as _i5.Future<_i3.SubPaginationModel>);
|
||||
},
|
||||
),
|
||||
)),
|
||||
returnValueForMissingStub:
|
||||
_i6.Future<_i3.SubPaginationModel>.value(_FakeSubPaginationModel_2(
|
||||
this,
|
||||
Invocation.method(
|
||||
#getSubscriptions,
|
||||
[],
|
||||
{
|
||||
#slug: slug,
|
||||
#query: query,
|
||||
},
|
||||
),
|
||||
)),
|
||||
) as _i6.Future<_i3.SubPaginationModel>);
|
||||
|
||||
@override
|
||||
_i5.Future<void> subscribe({required String? slug}) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(#subscribe, [], {#slug: slug}),
|
||||
returnValue: _i5.Future<void>.value(),
|
||||
returnValueForMissingStub: _i5.Future<void>.value(),
|
||||
)
|
||||
as _i5.Future<void>);
|
||||
_i6.Future<void> subscribe({required String? slug}) => (super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#subscribe,
|
||||
[],
|
||||
{#slug: slug},
|
||||
),
|
||||
returnValue: _i6.Future<void>.value(),
|
||||
returnValueForMissingStub: _i6.Future<void>.value(),
|
||||
) as _i6.Future<void>);
|
||||
|
||||
@override
|
||||
_i5.Future<void> unsubscribe({required String? slug}) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(#unsubscribe, [], {#slug: slug}),
|
||||
returnValue: _i5.Future<void>.value(),
|
||||
returnValueForMissingStub: _i5.Future<void>.value(),
|
||||
)
|
||||
as _i5.Future<void>);
|
||||
_i6.Future<void> unsubscribe({required String? slug}) => (super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#unsubscribe,
|
||||
[],
|
||||
{#slug: slug},
|
||||
),
|
||||
returnValue: _i6.Future<void>.value(),
|
||||
returnValueForMissingStub: _i6.Future<void>.value(),
|
||||
) as _i6.Future<void>);
|
||||
|
||||
@override
|
||||
_i5.Future<void> uploadPhoto({required _i9.File? photo}) =>
|
||||
_i6.Future<void> uploadPhoto({required _i10.File? photo}) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(#uploadPhoto, [], {#photo: photo}),
|
||||
returnValue: _i5.Future<void>.value(),
|
||||
returnValueForMissingStub: _i5.Future<void>.value(),
|
||||
)
|
||||
as _i5.Future<void>);
|
||||
Invocation.method(
|
||||
#uploadPhoto,
|
||||
[],
|
||||
{#photo: photo},
|
||||
),
|
||||
returnValue: _i6.Future<void>.value(),
|
||||
returnValueForMissingStub: _i6.Future<void>.value(),
|
||||
) as _i6.Future<void>);
|
||||
|
||||
@override
|
||||
_i5.Future<void> deletePhoto() =>
|
||||
_i6.Future<void> deletePhoto() => (super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#deletePhoto,
|
||||
[],
|
||||
),
|
||||
returnValue: _i6.Future<void>.value(),
|
||||
returnValueForMissingStub: _i6.Future<void>.value(),
|
||||
) as _i6.Future<void>);
|
||||
|
||||
@override
|
||||
_i6.Future<_i4.ChosenDietsPaginationModel> getChosenDiets() =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(#deletePhoto, []),
|
||||
returnValue: _i5.Future<void>.value(),
|
||||
returnValueForMissingStub: _i5.Future<void>.value(),
|
||||
)
|
||||
as _i5.Future<void>);
|
||||
Invocation.method(
|
||||
#getChosenDiets,
|
||||
[],
|
||||
),
|
||||
returnValue: _i6.Future<_i4.ChosenDietsPaginationModel>.value(
|
||||
_FakeChosenDietsPaginationModel_3(
|
||||
this,
|
||||
Invocation.method(
|
||||
#getChosenDiets,
|
||||
[],
|
||||
),
|
||||
)),
|
||||
returnValueForMissingStub:
|
||||
_i6.Future<_i4.ChosenDietsPaginationModel>.value(
|
||||
_FakeChosenDietsPaginationModel_3(
|
||||
this,
|
||||
Invocation.method(
|
||||
#getChosenDiets,
|
||||
[],
|
||||
),
|
||||
)),
|
||||
) as _i6.Future<_i4.ChosenDietsPaginationModel>);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user