forked from eatvio/eatvio_app
added dev tools
This commit is contained in:
@@ -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';
|
||||
@@ -302,6 +303,11 @@ class AppRouter {
|
||||
slug: state.extra as String,
|
||||
),
|
||||
),
|
||||
GoRoute(
|
||||
path: DevToolsScreen.path,
|
||||
name: DevToolsScreen.name,
|
||||
builder: (context, state) => DevToolsScreen(),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
@@ -71,7 +71,7 @@ class WsManager {
|
||||
}
|
||||
});
|
||||
client?.eventStream.listen((event) {
|
||||
log(event.rootObject.toString());
|
||||
// log(event.rootObject.toString());
|
||||
});
|
||||
_subscribe();
|
||||
} catch (e, st) {
|
||||
|
||||
@@ -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,
|
||||
);
|
||||
}
|
||||
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.com')
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -153,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 ||
|
||||
|
||||
@@ -150,7 +150,7 @@ class DietsCubit extends Cubit<DietsState> {
|
||||
|
||||
Future<void> likeDiet(int id, int index) async {
|
||||
final currentDiets = state.dietsList;
|
||||
if (currentDiets.isEmpty) return;
|
||||
// if (currentDiets.isEmpty) return;
|
||||
final dietsForModification = [...currentDiets];
|
||||
final currentDiet = currentDiets[index];
|
||||
if (currentDiet.wasLikedByMe) {
|
||||
|
||||
@@ -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,49 +2,70 @@ 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/dev_tools/presentation/dev_tools_screen.dart';
|
||||
import 'package:eatvio_app/features/dev_tools/test_cases.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/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/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(),
|
||||
),
|
||||
],
|
||||
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();
|
||||
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 List<String> chipsLabelList = ['Все', 'Рецепты', 'Диеты', 'Планы питания', 'Консультанты'];
|
||||
int _selectedChipIndex = 0;
|
||||
final blogPostsScrollController = ScrollController();
|
||||
@@ -54,7 +75,6 @@ class _FeedScreenState extends State<FeedScreen> {
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
feedCubit.loadFeedBlogPostList();
|
||||
blogPostsScrollController.addListener(_onScrollBlogPosts);
|
||||
recipesScrollController.addListener(_onScrollRecipes);
|
||||
dietsScrollController.addListener(_onScrollDiets);
|
||||
@@ -64,25 +84,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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -97,341 +117,139 @@ 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(),
|
||||
),
|
||||
],
|
||||
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,
|
||||
_ => 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;
|
||||
}
|
||||
},
|
||||
);
|
||||
} 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;
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
},
|
||||
),
|
||||
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()
|
||||
return Scaffold(
|
||||
floatingActionButton: _selectedChipIndex == 1
|
||||
? FloatingActionButton.small(
|
||||
heroTag: 'recipesTagsFilter',
|
||||
backgroundColor: appTheme.blueA400,
|
||||
shape: CircleBorder(),
|
||||
child: Icon(
|
||||
Icons.filter_list_rounded,
|
||||
color: Colors.white,
|
||||
),
|
||||
onPressed: () async {
|
||||
final recipesCubit = context.read<RecipesCubit>();
|
||||
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,
|
||||
_ => 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,
|
||||
_ => postsController,
|
||||
},
|
||||
],
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
];
|
||||
},
|
||||
body: switch (_selectedChipIndex) {
|
||||
0 => _buildAllBlogPosts(),
|
||||
1 => _buildAllRecipes(),
|
||||
2 => _buildDiets(),
|
||||
3 => _buildPlans(),
|
||||
_ => 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(),
|
||||
);
|
||||
}
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
_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]);
|
||||
},
|
||||
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(),
|
||||
);
|
||||
}
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
_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,
|
||||
),
|
||||
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;
|
||||
}
|
||||
},
|
||||
);
|
||||
} 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;
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
},
|
||||
),
|
||||
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()
|
||||
},
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
);
|
||||
},
|
||||
),
|
||||
];
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
_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(),
|
||||
_ => Center(child: Text(chipsLabelList[_selectedChipIndex])),
|
||||
},
|
||||
),
|
||||
);
|
||||
@@ -454,7 +272,6 @@ class _FeedScreenState extends State<FeedScreen> {
|
||||
onSelected: (bool selected) {
|
||||
setState(() {
|
||||
_selectedChipIndex = 0;
|
||||
searchController.clear();
|
||||
FocusScope.of(context).requestFocus(new FocusNode());
|
||||
});
|
||||
},
|
||||
@@ -467,7 +284,6 @@ class _FeedScreenState extends State<FeedScreen> {
|
||||
onSelected: (bool selected) {
|
||||
setState(() {
|
||||
_selectedChipIndex = 1;
|
||||
searchController.clear();
|
||||
FocusScope.of(context).requestFocus(new FocusNode());
|
||||
});
|
||||
},
|
||||
@@ -480,7 +296,6 @@ class _FeedScreenState extends State<FeedScreen> {
|
||||
onSelected: (bool selected) {
|
||||
setState(() {
|
||||
_selectedChipIndex = 2;
|
||||
searchController.clear();
|
||||
FocusScope.of(context).requestFocus(new FocusNode());
|
||||
});
|
||||
},
|
||||
@@ -493,7 +308,6 @@ class _FeedScreenState extends State<FeedScreen> {
|
||||
onSelected: (bool selected) {
|
||||
setState(() {
|
||||
_selectedChipIndex = 3;
|
||||
searchController.clear();
|
||||
FocusScope.of(context).requestFocus(new FocusNode());
|
||||
});
|
||||
},
|
||||
@@ -506,7 +320,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(),
|
||||
);
|
||||
}
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
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>(),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
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(),
|
||||
);
|
||||
}
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -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: () {},
|
||||
),
|
||||
_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,
|
||||
|
||||
@@ -47,7 +47,7 @@ class _MyDietsService implements MyDietsService {
|
||||
)
|
||||
.compose(
|
||||
_dio.options,
|
||||
'/api/diets/index',
|
||||
'/api/profile/my_diets',
|
||||
queryParameters: queryParameters,
|
||||
data: _data,
|
||||
)
|
||||
|
||||
@@ -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,
|
||||
};
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -596,6 +596,39 @@ class _ProfileService implements ProfileService {
|
||||
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 ||
|
||||
|
||||
@@ -3,18 +3,20 @@
|
||||
// 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
|
||||
@@ -62,19 +64,30 @@ class _FakeSubPaginationModel_2 extends _i1.SmartFake
|
||||
);
|
||||
}
|
||||
|
||||
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(
|
||||
returnValue: _i6.Future<_i2.ProfileModel>.value(_FakeProfileModel_0(
|
||||
this,
|
||||
Invocation.method(
|
||||
#getProfileBySlug,
|
||||
@@ -83,7 +96,7 @@ class MockProfileService extends _i1.Mock implements _i4.ProfileService {
|
||||
),
|
||||
)),
|
||||
returnValueForMissingStub:
|
||||
_i5.Future<_i2.ProfileModel>.value(_FakeProfileModel_0(
|
||||
_i6.Future<_i2.ProfileModel>.value(_FakeProfileModel_0(
|
||||
this,
|
||||
Invocation.method(
|
||||
#getProfileBySlug,
|
||||
@@ -91,15 +104,15 @@ class MockProfileService extends _i1.Mock implements _i4.ProfileService {
|
||||
{#slug: slug},
|
||||
),
|
||||
)),
|
||||
) as _i5.Future<_i2.ProfileModel>);
|
||||
) as _i6.Future<_i2.ProfileModel>);
|
||||
|
||||
@override
|
||||
_i5.Future<_i2.ProfileModel> getMyProfile() => (super.noSuchMethod(
|
||||
_i6.Future<_i2.ProfileModel> getMyProfile() => (super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#getMyProfile,
|
||||
[],
|
||||
),
|
||||
returnValue: _i5.Future<_i2.ProfileModel>.value(_FakeProfileModel_0(
|
||||
returnValue: _i6.Future<_i2.ProfileModel>.value(_FakeProfileModel_0(
|
||||
this,
|
||||
Invocation.method(
|
||||
#getMyProfile,
|
||||
@@ -107,23 +120,23 @@ class MockProfileService extends _i1.Mock implements _i4.ProfileService {
|
||||
),
|
||||
)),
|
||||
returnValueForMissingStub:
|
||||
_i5.Future<_i2.ProfileModel>.value(_FakeProfileModel_0(
|
||||
_i6.Future<_i2.ProfileModel>.value(_FakeProfileModel_0(
|
||||
this,
|
||||
Invocation.method(
|
||||
#getMyProfile,
|
||||
[],
|
||||
),
|
||||
)),
|
||||
) as _i5.Future<_i2.ProfileModel>);
|
||||
) 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(
|
||||
returnValue: _i6.Future<_i2.ProfileDetailsModel>.value(
|
||||
_FakeProfileDetailsModel_1(
|
||||
this,
|
||||
Invocation.method(
|
||||
@@ -131,7 +144,7 @@ class MockProfileService extends _i1.Mock implements _i4.ProfileService {
|
||||
[],
|
||||
),
|
||||
)),
|
||||
returnValueForMissingStub: _i5.Future<_i2.ProfileDetailsModel>.value(
|
||||
returnValueForMissingStub: _i6.Future<_i2.ProfileDetailsModel>.value(
|
||||
_FakeProfileDetailsModel_1(
|
||||
this,
|
||||
Invocation.method(
|
||||
@@ -139,10 +152,10 @@ class MockProfileService extends _i1.Mock implements _i4.ProfileService {
|
||||
[],
|
||||
),
|
||||
)),
|
||||
) as _i5.Future<_i2.ProfileDetailsModel>);
|
||||
) as _i6.Future<_i2.ProfileDetailsModel>);
|
||||
|
||||
@override
|
||||
_i5.Future<_i2.ProfileDetailsModel> getProfileDetailsBySlug(
|
||||
_i6.Future<_i2.ProfileDetailsModel> getProfileDetailsBySlug(
|
||||
{required String? slug}) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(
|
||||
@@ -150,7 +163,7 @@ class MockProfileService extends _i1.Mock implements _i4.ProfileService {
|
||||
[],
|
||||
{#slug: slug},
|
||||
),
|
||||
returnValue: _i5.Future<_i2.ProfileDetailsModel>.value(
|
||||
returnValue: _i6.Future<_i2.ProfileDetailsModel>.value(
|
||||
_FakeProfileDetailsModel_1(
|
||||
this,
|
||||
Invocation.method(
|
||||
@@ -159,7 +172,7 @@ class MockProfileService extends _i1.Mock implements _i4.ProfileService {
|
||||
{#slug: slug},
|
||||
),
|
||||
)),
|
||||
returnValueForMissingStub: _i5.Future<_i2.ProfileDetailsModel>.value(
|
||||
returnValueForMissingStub: _i6.Future<_i2.ProfileDetailsModel>.value(
|
||||
_FakeProfileDetailsModel_1(
|
||||
this,
|
||||
Invocation.method(
|
||||
@@ -168,10 +181,10 @@ class MockProfileService extends _i1.Mock implements _i4.ProfileService {
|
||||
{#slug: slug},
|
||||
),
|
||||
)),
|
||||
) as _i5.Future<_i2.ProfileDetailsModel>);
|
||||
) as _i6.Future<_i2.ProfileDetailsModel>);
|
||||
|
||||
@override
|
||||
_i5.Future<void> addCircumference({
|
||||
_i6.Future<void> addCircumference({
|
||||
required int? chestCircumference,
|
||||
required int? waistCircumference,
|
||||
required int? hipCircumference,
|
||||
@@ -186,23 +199,23 @@ class MockProfileService extends _i1.Mock implements _i4.ProfileService {
|
||||
#hipCircumference: hipCircumference,
|
||||
},
|
||||
),
|
||||
returnValue: _i5.Future<void>.value(),
|
||||
returnValueForMissingStub: _i5.Future<void>.value(),
|
||||
) as _i5.Future<void>);
|
||||
returnValue: _i6.Future<void>.value(),
|
||||
returnValueForMissingStub: _i6.Future<void>.value(),
|
||||
) as _i6.Future<void>);
|
||||
|
||||
@override
|
||||
_i5.Future<void> addWeight({required double? weight}) => (super.noSuchMethod(
|
||||
_i6.Future<void> addWeight({required double? weight}) => (super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#addWeight,
|
||||
[],
|
||||
{#weight: weight},
|
||||
),
|
||||
returnValue: _i5.Future<void>.value(),
|
||||
returnValueForMissingStub: _i5.Future<void>.value(),
|
||||
) as _i5.Future<void>);
|
||||
returnValue: _i6.Future<void>.value(),
|
||||
returnValueForMissingStub: _i6.Future<void>.value(),
|
||||
) as _i6.Future<void>);
|
||||
|
||||
@override
|
||||
_i5.Future<List<_i6.FeedBlogPostModel>> getBlogPostByAuthorSlug(
|
||||
_i6.Future<List<_i7.FeedBlogPostModel>> getBlogPostByAuthorSlug(
|
||||
{required String? slug}) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(
|
||||
@@ -210,15 +223,15 @@ class MockProfileService extends _i1.Mock implements _i4.ProfileService {
|
||||
[],
|
||||
{#slug: slug},
|
||||
),
|
||||
returnValue: _i5.Future<List<_i6.FeedBlogPostModel>>.value(
|
||||
<_i6.FeedBlogPostModel>[]),
|
||||
returnValue: _i6.Future<List<_i7.FeedBlogPostModel>>.value(
|
||||
<_i7.FeedBlogPostModel>[]),
|
||||
returnValueForMissingStub:
|
||||
_i5.Future<List<_i6.FeedBlogPostModel>>.value(
|
||||
<_i6.FeedBlogPostModel>[]),
|
||||
) as _i5.Future<List<_i6.FeedBlogPostModel>>);
|
||||
_i6.Future<List<_i7.FeedBlogPostModel>>.value(
|
||||
<_i7.FeedBlogPostModel>[]),
|
||||
) as _i6.Future<List<_i7.FeedBlogPostModel>>);
|
||||
|
||||
@override
|
||||
_i5.Future<List<_i7.WeightModel>> getWeight({required String? period}) =>
|
||||
_i6.Future<List<_i8.WeightModel>> getWeight({required String? period}) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#getWeight,
|
||||
@@ -226,13 +239,13 @@ class MockProfileService extends _i1.Mock implements _i4.ProfileService {
|
||||
{#period: period},
|
||||
),
|
||||
returnValue:
|
||||
_i5.Future<List<_i7.WeightModel>>.value(<_i7.WeightModel>[]),
|
||||
_i6.Future<List<_i8.WeightModel>>.value(<_i8.WeightModel>[]),
|
||||
returnValueForMissingStub:
|
||||
_i5.Future<List<_i7.WeightModel>>.value(<_i7.WeightModel>[]),
|
||||
) as _i5.Future<List<_i7.WeightModel>>);
|
||||
_i6.Future<List<_i8.WeightModel>>.value(<_i8.WeightModel>[]),
|
||||
) as _i6.Future<List<_i8.WeightModel>>);
|
||||
|
||||
@override
|
||||
_i5.Future<List<_i7.WeightModel>> getWeightBySlug({
|
||||
_i6.Future<List<_i8.WeightModel>> getWeightBySlug({
|
||||
required String? period,
|
||||
required String? slug,
|
||||
}) =>
|
||||
@@ -246,13 +259,13 @@ class MockProfileService extends _i1.Mock implements _i4.ProfileService {
|
||||
},
|
||||
),
|
||||
returnValue:
|
||||
_i5.Future<List<_i7.WeightModel>>.value(<_i7.WeightModel>[]),
|
||||
_i6.Future<List<_i8.WeightModel>>.value(<_i8.WeightModel>[]),
|
||||
returnValueForMissingStub:
|
||||
_i5.Future<List<_i7.WeightModel>>.value(<_i7.WeightModel>[]),
|
||||
) as _i5.Future<List<_i7.WeightModel>>);
|
||||
_i6.Future<List<_i8.WeightModel>>.value(<_i8.WeightModel>[]),
|
||||
) as _i6.Future<List<_i8.WeightModel>>);
|
||||
|
||||
@override
|
||||
_i5.Future<List<_i8.CircumferenceModel>> getCircumferences(
|
||||
_i6.Future<List<_i9.CircumferenceModel>> getCircumferences(
|
||||
{required String? period}) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(
|
||||
@@ -260,15 +273,15 @@ class MockProfileService extends _i1.Mock implements _i4.ProfileService {
|
||||
[],
|
||||
{#period: period},
|
||||
),
|
||||
returnValue: _i5.Future<List<_i8.CircumferenceModel>>.value(
|
||||
<_i8.CircumferenceModel>[]),
|
||||
returnValue: _i6.Future<List<_i9.CircumferenceModel>>.value(
|
||||
<_i9.CircumferenceModel>[]),
|
||||
returnValueForMissingStub:
|
||||
_i5.Future<List<_i8.CircumferenceModel>>.value(
|
||||
<_i8.CircumferenceModel>[]),
|
||||
) as _i5.Future<List<_i8.CircumferenceModel>>);
|
||||
_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,
|
||||
}) =>
|
||||
@@ -281,15 +294,15 @@ class MockProfileService extends _i1.Mock implements _i4.ProfileService {
|
||||
#slug: slug,
|
||||
},
|
||||
),
|
||||
returnValue: _i5.Future<List<_i8.CircumferenceModel>>.value(
|
||||
<_i8.CircumferenceModel>[]),
|
||||
returnValue: _i6.Future<List<_i9.CircumferenceModel>>.value(
|
||||
<_i9.CircumferenceModel>[]),
|
||||
returnValueForMissingStub:
|
||||
_i5.Future<List<_i8.CircumferenceModel>>.value(
|
||||
<_i8.CircumferenceModel>[]),
|
||||
) as _i5.Future<List<_i8.CircumferenceModel>>);
|
||||
_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,
|
||||
}) =>
|
||||
@@ -303,7 +316,7 @@ class MockProfileService extends _i1.Mock implements _i4.ProfileService {
|
||||
},
|
||||
),
|
||||
returnValue:
|
||||
_i5.Future<_i3.SubPaginationModel>.value(_FakeSubPaginationModel_2(
|
||||
_i6.Future<_i3.SubPaginationModel>.value(_FakeSubPaginationModel_2(
|
||||
this,
|
||||
Invocation.method(
|
||||
#getSubscribers,
|
||||
@@ -315,7 +328,7 @@ class MockProfileService extends _i1.Mock implements _i4.ProfileService {
|
||||
),
|
||||
)),
|
||||
returnValueForMissingStub:
|
||||
_i5.Future<_i3.SubPaginationModel>.value(_FakeSubPaginationModel_2(
|
||||
_i6.Future<_i3.SubPaginationModel>.value(_FakeSubPaginationModel_2(
|
||||
this,
|
||||
Invocation.method(
|
||||
#getSubscribers,
|
||||
@@ -326,10 +339,10 @@ class MockProfileService extends _i1.Mock implements _i4.ProfileService {
|
||||
},
|
||||
),
|
||||
)),
|
||||
) as _i5.Future<_i3.SubPaginationModel>);
|
||||
) as _i6.Future<_i3.SubPaginationModel>);
|
||||
|
||||
@override
|
||||
_i5.Future<_i3.SubPaginationModel> getSubscriptions({
|
||||
_i6.Future<_i3.SubPaginationModel> getSubscriptions({
|
||||
required String? slug,
|
||||
String? query,
|
||||
}) =>
|
||||
@@ -343,7 +356,7 @@ class MockProfileService extends _i1.Mock implements _i4.ProfileService {
|
||||
},
|
||||
),
|
||||
returnValue:
|
||||
_i5.Future<_i3.SubPaginationModel>.value(_FakeSubPaginationModel_2(
|
||||
_i6.Future<_i3.SubPaginationModel>.value(_FakeSubPaginationModel_2(
|
||||
this,
|
||||
Invocation.method(
|
||||
#getSubscriptions,
|
||||
@@ -355,7 +368,7 @@ class MockProfileService extends _i1.Mock implements _i4.ProfileService {
|
||||
),
|
||||
)),
|
||||
returnValueForMissingStub:
|
||||
_i5.Future<_i3.SubPaginationModel>.value(_FakeSubPaginationModel_2(
|
||||
_i6.Future<_i3.SubPaginationModel>.value(_FakeSubPaginationModel_2(
|
||||
this,
|
||||
Invocation.method(
|
||||
#getSubscriptions,
|
||||
@@ -366,49 +379,75 @@ class MockProfileService extends _i1.Mock implements _i4.ProfileService {
|
||||
},
|
||||
),
|
||||
)),
|
||||
) as _i5.Future<_i3.SubPaginationModel>);
|
||||
) as _i6.Future<_i3.SubPaginationModel>);
|
||||
|
||||
@override
|
||||
_i5.Future<void> subscribe({required String? slug}) => (super.noSuchMethod(
|
||||
_i6.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>);
|
||||
returnValue: _i6.Future<void>.value(),
|
||||
returnValueForMissingStub: _i6.Future<void>.value(),
|
||||
) as _i6.Future<void>);
|
||||
|
||||
@override
|
||||
_i5.Future<void> unsubscribe({required String? slug}) => (super.noSuchMethod(
|
||||
_i6.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>);
|
||||
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>);
|
||||
returnValue: _i6.Future<void>.value(),
|
||||
returnValueForMissingStub: _i6.Future<void>.value(),
|
||||
) as _i6.Future<void>);
|
||||
|
||||
@override
|
||||
_i5.Future<void> deletePhoto() => (super.noSuchMethod(
|
||||
_i6.Future<void> deletePhoto() => (super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#deletePhoto,
|
||||
[],
|
||||
),
|
||||
returnValue: _i5.Future<void>.value(),
|
||||
returnValueForMissingStub: _i5.Future<void>.value(),
|
||||
) as _i5.Future<void>);
|
||||
returnValue: _i6.Future<void>.value(),
|
||||
returnValueForMissingStub: _i6.Future<void>.value(),
|
||||
) as _i6.Future<void>);
|
||||
|
||||
@override
|
||||
_i6.Future<_i4.ChosenDietsPaginationModel> getChosenDiets() =>
|
||||
(super.noSuchMethod(
|
||||
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