forked from eatvio/eatvio_app
Merge pull request 'feature/consultant' (#1) from feature/consultant into main
Reviewed-on: mso7nueh/eatvio_app#1
This commit is contained in:
@@ -7,6 +7,8 @@ import 'package:eatvio_app/features/calendar/presentation/pages/calendar_screen.
|
||||
import 'package:eatvio_app/features/chat/presentation/pages/chat_screen.dart';
|
||||
import 'package:eatvio_app/features/chat/presentation/pages/chat_select_screen.dart';
|
||||
import 'package:eatvio_app/features/chat/presentation/pages/photo_view_screen.dart';
|
||||
import 'package:eatvio_app/features/consultant/become_consultant/pages/become_consultant_screen.dart';
|
||||
import 'package:eatvio_app/features/consultant/become_consultant/pages/stepper_become_consultant_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';
|
||||
@@ -221,6 +223,15 @@ class AppRouter {
|
||||
name: 'mySettingsScreen',
|
||||
builder: (context, state) => MySettingsScreen.builder(context),
|
||||
),
|
||||
GoRoute(
|
||||
path: '/become-consultant-screen',
|
||||
name: 'becomeConsultantScreen',
|
||||
builder: (context, state) => BecomeConsultantScreen(),
|
||||
),GoRoute(
|
||||
path: '/stepper-become-consultant-screen',
|
||||
name: 'stepperBecomeConsultantScreen',
|
||||
builder: (context, state) => StepperBecomeConsultantScreen(),
|
||||
),
|
||||
GoRoute(
|
||||
path: '/recipe-select-screen',
|
||||
name: 'recipeSelectScreen',
|
||||
|
||||
@@ -27,16 +27,18 @@ class ChatScreen extends StatefulWidget {
|
||||
class _ChatScreenState extends State<ChatScreen> {
|
||||
final scrollController = ScrollController();
|
||||
final TextEditingController textEditingController = TextEditingController();
|
||||
final ChatRoomCubit chatRoomCubit = sl<ChatRoomCubit>();
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
scrollController.addListener(_onScroll);
|
||||
super.initState();
|
||||
scrollController.addListener(_onScroll);
|
||||
chatRoomCubit.initChat(widget.chatId);
|
||||
}
|
||||
|
||||
_onScroll() {
|
||||
if (scrollController.offset >= scrollController.position.maxScrollExtent && !scrollController.position.outOfRange) {
|
||||
context.read<ChatRoomCubit>().loadNextPage(widget.chatId);
|
||||
chatRoomCubit.loadNextPage(widget.chatId);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,8 +50,9 @@ class _ChatScreenState extends State<ChatScreen> {
|
||||
|
||||
Widget build(BuildContext context) {
|
||||
return BlocProvider<ChatRoomCubit>(
|
||||
create: (BuildContext context) => sl()..initChat(widget.chatId),
|
||||
create: (BuildContext context) => chatRoomCubit,
|
||||
child: BlocBuilder<ChatRoomCubit, ChatRoomState>(
|
||||
bloc: chatRoomCubit,
|
||||
builder: (context, state) {
|
||||
if (state is ChatRoomStateLoaded) {
|
||||
return _buildChat(context, state);
|
||||
@@ -234,7 +237,7 @@ class _ChatScreenState extends State<ChatScreen> {
|
||||
|
||||
if (result != null) {
|
||||
List<File> files = result.paths.map((path) => File(path!)).toList();
|
||||
context.read<ChatRoomCubit>().sendMessage(
|
||||
chatRoomCubit.sendMessage(
|
||||
chatId: widget.chatId,
|
||||
files: files,
|
||||
);
|
||||
@@ -305,7 +308,7 @@ class _ChatScreenState extends State<ChatScreen> {
|
||||
customBorder: CircleBorder(),
|
||||
onTap: () {
|
||||
if (textEditingController.text.isNotEmpty) {
|
||||
context.read<ChatRoomCubit>().sendMessage(
|
||||
chatRoomCubit.sendMessage(
|
||||
chatId: widget.chatId,
|
||||
data: textEditingController.text.trim(),
|
||||
);
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
import 'package:eatvio_app/theme/theme_helper.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
|
||||
class BecomeConsultantScreen extends StatefulWidget {
|
||||
const BecomeConsultantScreen({super.key});
|
||||
|
||||
@override
|
||||
State<BecomeConsultantScreen> createState() => _BecomeConsultantScreenState();
|
||||
}
|
||||
|
||||
class _BecomeConsultantScreenState extends State<BecomeConsultantScreen> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: Text('Стать консультантом'),
|
||||
automaticallyImplyLeading: false,
|
||||
centerTitle: false,
|
||||
leading: IconButton(
|
||||
onPressed: () => GoRouter.of(context).pop(),
|
||||
icon: Icon(Icons.close),
|
||||
),
|
||||
),
|
||||
body: Padding(
|
||||
padding: const EdgeInsets.all(16),
|
||||
child: Text('Для регистрации потребуется следующий список документов, подготовьте их заранее'),
|
||||
),
|
||||
bottomSheet: _startRegistrationButton(),
|
||||
);
|
||||
}
|
||||
|
||||
_startRegistrationButton() {
|
||||
return InkWell(
|
||||
onTap: () => GoRouter.of(context).pushReplacementNamed('stepperBecomeConsultantScreen'),
|
||||
borderRadius: BorderRadius.circular(20),
|
||||
child: Ink(
|
||||
height: 52,
|
||||
width: MediaQuery.of(context).size.width - 32,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(20),
|
||||
color: appTheme.blueA400,
|
||||
),
|
||||
child: Center(
|
||||
child: Text(
|
||||
'Начать регистрацию',
|
||||
style: TextStyle(
|
||||
color: Colors.white,
|
||||
height: 1,
|
||||
fontWeight: FontWeight.w600,
|
||||
fontSize: 18,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,139 @@
|
||||
import 'package:eatvio_app/core/utils/image_constant.dart';
|
||||
import 'package:eatvio_app/theme/theme_helper.dart';
|
||||
import 'package:eatvio_app/widgets/app_bar/appbar_title_image.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
|
||||
class StepperBecomeConsultantScreen extends StatefulWidget {
|
||||
const StepperBecomeConsultantScreen({super.key});
|
||||
|
||||
@override
|
||||
State<StepperBecomeConsultantScreen> createState() => _StepperBecomeConsultantScreenState();
|
||||
}
|
||||
|
||||
class _StepperBecomeConsultantScreenState extends State<StepperBecomeConsultantScreen> {
|
||||
double progressValue = 1 / 6;
|
||||
int step = 1;
|
||||
final pageController = PageController();
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat,
|
||||
floatingActionButton: Row(
|
||||
children: [
|
||||
Container(
|
||||
height: 48,
|
||||
width: MediaQuery.of(context).size.width * 0.2,
|
||||
padding: EdgeInsets.only(left: 16, right: 4),
|
||||
child: FloatingActionButton.extended(
|
||||
heroTag: 'backButtonRegistration',
|
||||
highlightElevation: 0,
|
||||
focusElevation: 0,
|
||||
elevation: 0,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(20),
|
||||
),
|
||||
backgroundColor: Color(0xFFEAF2FD),
|
||||
onPressed: () async {
|
||||
setState(() {
|
||||
pageController.previousPage(
|
||||
duration: const Duration(milliseconds: 350),
|
||||
curve: Curves.easeInOut,
|
||||
);
|
||||
});
|
||||
},
|
||||
label: Icon(
|
||||
Icons.arrow_back_ios_new_rounded,
|
||||
color: appTheme.blueA400,
|
||||
),
|
||||
),
|
||||
),
|
||||
Container(
|
||||
height: 48,
|
||||
width: MediaQuery.of(context).size.width * 0.8,
|
||||
padding: EdgeInsets.only(left: 4, right: 16),
|
||||
child: FloatingActionButton.extended(
|
||||
heroTag: 'nextButtonRegistration',
|
||||
highlightElevation: 0,
|
||||
elevation: 0,
|
||||
focusElevation: 0,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(20),
|
||||
),
|
||||
backgroundColor: appTheme.blueA400,
|
||||
onPressed: () async {
|
||||
setState(() {
|
||||
pageController.nextPage(
|
||||
duration: const Duration(milliseconds: 350),
|
||||
curve: Curves.easeInOut,
|
||||
);
|
||||
});
|
||||
},
|
||||
label: Text(
|
||||
'Продолжить',
|
||||
style: theme.textTheme.titleSmall!.copyWith(color: Colors.white),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
appBar: AppBar(
|
||||
automaticallyImplyLeading: false,
|
||||
leading: Builder(
|
||||
builder: (context) => IconButton(
|
||||
icon: Icon(Icons.close_rounded),
|
||||
onPressed: () => GoRouter.of(context).pop(),
|
||||
),
|
||||
),
|
||||
centerTitle: true,
|
||||
title: AppbarTitleImage(imagePath: ImageConstant.imgLogoEatvio),
|
||||
actions: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(right: 16),
|
||||
child: Text('шаг $step из 6'),
|
||||
),
|
||||
],
|
||||
bottom: PreferredSize(
|
||||
preferredSize: Size(MediaQuery.of(context).size.width, 32),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(16),
|
||||
child: TweenAnimationBuilder<double>(
|
||||
duration: const Duration(milliseconds: 350),
|
||||
curve: Curves.easeInOut,
|
||||
tween: Tween<double>(
|
||||
begin: 0,
|
||||
end: progressValue,
|
||||
),
|
||||
builder: (context, value, _) => LinearProgressIndicator(
|
||||
value: value,
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
minHeight: 8,
|
||||
backgroundColor: Colors.grey.shade100,
|
||||
valueColor: AlwaysStoppedAnimation<Color>(appTheme.blueA400),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
body: PageView(
|
||||
physics: NeverScrollableScrollPhysics(),
|
||||
controller: pageController,
|
||||
onPageChanged: (index) {
|
||||
setState(() {
|
||||
step = index + 1;
|
||||
progressValue = step / 6;
|
||||
});
|
||||
},
|
||||
children: [
|
||||
Container(),
|
||||
Container(),
|
||||
Container(),
|
||||
Container(),
|
||||
Container(),
|
||||
Container(),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -4,15 +4,60 @@ import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
|
||||
class DietsCubit extends Cubit<DietsState> {
|
||||
final FeedRepository feedRepository;
|
||||
int currentPage = 1;
|
||||
late int lastPage;
|
||||
bool isLoading = false;
|
||||
String? _query;
|
||||
|
||||
DietsCubit({required this.feedRepository}) : super(const DietsState.loading());
|
||||
|
||||
loadDiets() async {
|
||||
loadDiets({
|
||||
String? query,
|
||||
}) async {
|
||||
try {
|
||||
final diets = await feedRepository.getDiets();
|
||||
emit(DietsState.loaded(diets: diets));
|
||||
_query = query;
|
||||
final dietsPagination = await feedRepository.getDiets(
|
||||
query: query,
|
||||
);
|
||||
lastPage = dietsPagination.meta.lastPage;
|
||||
emit(DietsState.loaded(
|
||||
dietsList: dietsPagination.data,
|
||||
isLoading: isLoading,
|
||||
));
|
||||
} catch (e) {
|
||||
emit(DietsState.error(errorMessage: e.toString()));
|
||||
emit(DietsState.error(
|
||||
errorMessage: e.toString(),
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
loadNextPage() async {
|
||||
if (currentPage < lastPage && !isLoading) {
|
||||
isLoading = true;
|
||||
|
||||
emit((state as DietsStateLoaded).copyWith(isLoading: isLoading));
|
||||
|
||||
try {
|
||||
if (currentPage < lastPage) {
|
||||
currentPage++;
|
||||
final dietPagination = await feedRepository.getDiets(
|
||||
page: currentPage,
|
||||
query: _query,
|
||||
);
|
||||
isLoading = false;
|
||||
emit(
|
||||
DietsState.loaded(
|
||||
dietsList: [
|
||||
...(state as DietsStateLoaded).dietsList,
|
||||
...dietPagination.data,
|
||||
],
|
||||
isLoading: isLoading,
|
||||
),
|
||||
);
|
||||
}
|
||||
} catch (e) {
|
||||
emit(DietsState.error(errorMessage: e.toString()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,7 +10,8 @@ abstract class DietsState with _$DietsState {
|
||||
const factory DietsState.loading() = DietsStateLoading;
|
||||
|
||||
const factory DietsState.loaded({
|
||||
required DietsPagination diets,
|
||||
required List<Diet> dietsList,
|
||||
required bool isLoading,
|
||||
}) = DietsStateLoaded;
|
||||
|
||||
const factory DietsState.error({
|
||||
|
||||
@@ -20,7 +20,7 @@ mixin _$DietsState {
|
||||
TResult when<TResult extends Object?>(
|
||||
TResult Function() $default, {
|
||||
required TResult Function() loading,
|
||||
required TResult Function(DietsPagination diets) loaded,
|
||||
required TResult Function(List<Diet> dietsList, bool isLoading) loaded,
|
||||
required TResult Function(String errorMessage) error,
|
||||
}) =>
|
||||
throw _privateConstructorUsedError;
|
||||
@@ -28,7 +28,7 @@ mixin _$DietsState {
|
||||
TResult? whenOrNull<TResult extends Object?>(
|
||||
TResult? Function()? $default, {
|
||||
TResult? Function()? loading,
|
||||
TResult? Function(DietsPagination diets)? loaded,
|
||||
TResult? Function(List<Diet> dietsList, bool isLoading)? loaded,
|
||||
TResult? Function(String errorMessage)? error,
|
||||
}) =>
|
||||
throw _privateConstructorUsedError;
|
||||
@@ -36,7 +36,7 @@ mixin _$DietsState {
|
||||
TResult maybeWhen<TResult extends Object?>(
|
||||
TResult Function()? $default, {
|
||||
TResult Function()? loading,
|
||||
TResult Function(DietsPagination diets)? loaded,
|
||||
TResult Function(List<Diet> dietsList, bool isLoading)? loaded,
|
||||
TResult Function(String errorMessage)? error,
|
||||
required TResult orElse(),
|
||||
}) =>
|
||||
@@ -132,7 +132,7 @@ class _$DietsStateImpl implements _DietsState {
|
||||
TResult when<TResult extends Object?>(
|
||||
TResult Function() $default, {
|
||||
required TResult Function() loading,
|
||||
required TResult Function(DietsPagination diets) loaded,
|
||||
required TResult Function(List<Diet> dietsList, bool isLoading) loaded,
|
||||
required TResult Function(String errorMessage) error,
|
||||
}) {
|
||||
return $default();
|
||||
@@ -143,7 +143,7 @@ class _$DietsStateImpl implements _DietsState {
|
||||
TResult? whenOrNull<TResult extends Object?>(
|
||||
TResult? Function()? $default, {
|
||||
TResult? Function()? loading,
|
||||
TResult? Function(DietsPagination diets)? loaded,
|
||||
TResult? Function(List<Diet> dietsList, bool isLoading)? loaded,
|
||||
TResult? Function(String errorMessage)? error,
|
||||
}) {
|
||||
return $default?.call();
|
||||
@@ -154,7 +154,7 @@ class _$DietsStateImpl implements _DietsState {
|
||||
TResult maybeWhen<TResult extends Object?>(
|
||||
TResult Function()? $default, {
|
||||
TResult Function()? loading,
|
||||
TResult Function(DietsPagination diets)? loaded,
|
||||
TResult Function(List<Diet> dietsList, bool isLoading)? loaded,
|
||||
TResult Function(String errorMessage)? error,
|
||||
required TResult orElse(),
|
||||
}) {
|
||||
@@ -249,7 +249,7 @@ class _$DietsStateLoadingImpl implements DietsStateLoading {
|
||||
TResult when<TResult extends Object?>(
|
||||
TResult Function() $default, {
|
||||
required TResult Function() loading,
|
||||
required TResult Function(DietsPagination diets) loaded,
|
||||
required TResult Function(List<Diet> dietsList, bool isLoading) loaded,
|
||||
required TResult Function(String errorMessage) error,
|
||||
}) {
|
||||
return loading();
|
||||
@@ -260,7 +260,7 @@ class _$DietsStateLoadingImpl implements DietsStateLoading {
|
||||
TResult? whenOrNull<TResult extends Object?>(
|
||||
TResult? Function()? $default, {
|
||||
TResult? Function()? loading,
|
||||
TResult? Function(DietsPagination diets)? loaded,
|
||||
TResult? Function(List<Diet> dietsList, bool isLoading)? loaded,
|
||||
TResult? Function(String errorMessage)? error,
|
||||
}) {
|
||||
return loading?.call();
|
||||
@@ -271,7 +271,7 @@ class _$DietsStateLoadingImpl implements DietsStateLoading {
|
||||
TResult maybeWhen<TResult extends Object?>(
|
||||
TResult Function()? $default, {
|
||||
TResult Function()? loading,
|
||||
TResult Function(DietsPagination diets)? loaded,
|
||||
TResult Function(List<Diet> dietsList, bool isLoading)? loaded,
|
||||
TResult Function(String errorMessage)? error,
|
||||
required TResult orElse(),
|
||||
}) {
|
||||
@@ -329,9 +329,7 @@ abstract class _$$DietsStateLoadedImplCopyWith<$Res> {
|
||||
$Res Function(_$DietsStateLoadedImpl) then) =
|
||||
__$$DietsStateLoadedImplCopyWithImpl<$Res>;
|
||||
@useResult
|
||||
$Res call({DietsPagination diets});
|
||||
|
||||
$DietsPaginationCopyWith<$Res> get diets;
|
||||
$Res call({List<Diet> dietsList, bool isLoading});
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
@@ -347,38 +345,43 @@ class __$$DietsStateLoadedImplCopyWithImpl<$Res>
|
||||
@pragma('vm:prefer-inline')
|
||||
@override
|
||||
$Res call({
|
||||
Object? diets = null,
|
||||
Object? dietsList = null,
|
||||
Object? isLoading = null,
|
||||
}) {
|
||||
return _then(_$DietsStateLoadedImpl(
|
||||
diets: null == diets
|
||||
? _value.diets
|
||||
: diets // ignore: cast_nullable_to_non_nullable
|
||||
as DietsPagination,
|
||||
dietsList: null == dietsList
|
||||
? _value._dietsList
|
||||
: dietsList // ignore: cast_nullable_to_non_nullable
|
||||
as List<Diet>,
|
||||
isLoading: null == isLoading
|
||||
? _value.isLoading
|
||||
: isLoading // ignore: cast_nullable_to_non_nullable
|
||||
as bool,
|
||||
));
|
||||
}
|
||||
|
||||
/// Create a copy of DietsState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override
|
||||
@pragma('vm:prefer-inline')
|
||||
$DietsPaginationCopyWith<$Res> get diets {
|
||||
return $DietsPaginationCopyWith<$Res>(_value.diets, (value) {
|
||||
return _then(_value.copyWith(diets: value));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
|
||||
class _$DietsStateLoadedImpl implements DietsStateLoaded {
|
||||
const _$DietsStateLoadedImpl({required this.diets});
|
||||
const _$DietsStateLoadedImpl(
|
||||
{required final List<Diet> dietsList, required this.isLoading})
|
||||
: _dietsList = dietsList;
|
||||
|
||||
final List<Diet> _dietsList;
|
||||
@override
|
||||
List<Diet> get dietsList {
|
||||
if (_dietsList is EqualUnmodifiableListView) return _dietsList;
|
||||
// ignore: implicit_dynamic_type
|
||||
return EqualUnmodifiableListView(_dietsList);
|
||||
}
|
||||
|
||||
@override
|
||||
final DietsPagination diets;
|
||||
final bool isLoading;
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'DietsState.loaded(diets: $diets)';
|
||||
return 'DietsState.loaded(dietsList: $dietsList, isLoading: $isLoading)';
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -386,11 +389,15 @@ class _$DietsStateLoadedImpl implements DietsStateLoaded {
|
||||
return identical(this, other) ||
|
||||
(other.runtimeType == runtimeType &&
|
||||
other is _$DietsStateLoadedImpl &&
|
||||
(identical(other.diets, diets) || other.diets == diets));
|
||||
const DeepCollectionEquality()
|
||||
.equals(other._dietsList, _dietsList) &&
|
||||
(identical(other.isLoading, isLoading) ||
|
||||
other.isLoading == isLoading));
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType, diets);
|
||||
int get hashCode => Object.hash(
|
||||
runtimeType, const DeepCollectionEquality().hash(_dietsList), isLoading);
|
||||
|
||||
/// Create a copy of DietsState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@@ -406,10 +413,10 @@ class _$DietsStateLoadedImpl implements DietsStateLoaded {
|
||||
TResult when<TResult extends Object?>(
|
||||
TResult Function() $default, {
|
||||
required TResult Function() loading,
|
||||
required TResult Function(DietsPagination diets) loaded,
|
||||
required TResult Function(List<Diet> dietsList, bool isLoading) loaded,
|
||||
required TResult Function(String errorMessage) error,
|
||||
}) {
|
||||
return loaded(diets);
|
||||
return loaded(dietsList, isLoading);
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -417,10 +424,10 @@ class _$DietsStateLoadedImpl implements DietsStateLoaded {
|
||||
TResult? whenOrNull<TResult extends Object?>(
|
||||
TResult? Function()? $default, {
|
||||
TResult? Function()? loading,
|
||||
TResult? Function(DietsPagination diets)? loaded,
|
||||
TResult? Function(List<Diet> dietsList, bool isLoading)? loaded,
|
||||
TResult? Function(String errorMessage)? error,
|
||||
}) {
|
||||
return loaded?.call(diets);
|
||||
return loaded?.call(dietsList, isLoading);
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -428,12 +435,12 @@ class _$DietsStateLoadedImpl implements DietsStateLoaded {
|
||||
TResult maybeWhen<TResult extends Object?>(
|
||||
TResult Function()? $default, {
|
||||
TResult Function()? loading,
|
||||
TResult Function(DietsPagination diets)? loaded,
|
||||
TResult Function(List<Diet> dietsList, bool isLoading)? loaded,
|
||||
TResult Function(String errorMessage)? error,
|
||||
required TResult orElse(),
|
||||
}) {
|
||||
if (loaded != null) {
|
||||
return loaded(diets);
|
||||
return loaded(dietsList, isLoading);
|
||||
}
|
||||
return orElse();
|
||||
}
|
||||
@@ -477,10 +484,12 @@ class _$DietsStateLoadedImpl implements DietsStateLoaded {
|
||||
}
|
||||
|
||||
abstract class DietsStateLoaded implements DietsState {
|
||||
const factory DietsStateLoaded({required final DietsPagination diets}) =
|
||||
_$DietsStateLoadedImpl;
|
||||
const factory DietsStateLoaded(
|
||||
{required final List<Diet> dietsList,
|
||||
required final bool isLoading}) = _$DietsStateLoadedImpl;
|
||||
|
||||
DietsPagination get diets;
|
||||
List<Diet> get dietsList;
|
||||
bool get isLoading;
|
||||
|
||||
/// Create a copy of DietsState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@@ -561,7 +570,7 @@ class _$DietsStateErrorImpl implements DietsStateError {
|
||||
TResult when<TResult extends Object?>(
|
||||
TResult Function() $default, {
|
||||
required TResult Function() loading,
|
||||
required TResult Function(DietsPagination diets) loaded,
|
||||
required TResult Function(List<Diet> dietsList, bool isLoading) loaded,
|
||||
required TResult Function(String errorMessage) error,
|
||||
}) {
|
||||
return error(errorMessage);
|
||||
@@ -572,7 +581,7 @@ class _$DietsStateErrorImpl implements DietsStateError {
|
||||
TResult? whenOrNull<TResult extends Object?>(
|
||||
TResult? Function()? $default, {
|
||||
TResult? Function()? loading,
|
||||
TResult? Function(DietsPagination diets)? loaded,
|
||||
TResult? Function(List<Diet> dietsList, bool isLoading)? loaded,
|
||||
TResult? Function(String errorMessage)? error,
|
||||
}) {
|
||||
return error?.call(errorMessage);
|
||||
@@ -583,7 +592,7 @@ class _$DietsStateErrorImpl implements DietsStateError {
|
||||
TResult maybeWhen<TResult extends Object?>(
|
||||
TResult Function()? $default, {
|
||||
TResult Function()? loading,
|
||||
TResult Function(DietsPagination diets)? loaded,
|
||||
TResult Function(List<Diet> dietsList, bool isLoading)? loaded,
|
||||
TResult Function(String errorMessage)? error,
|
||||
required TResult orElse(),
|
||||
}) {
|
||||
|
||||
@@ -37,7 +37,9 @@ class FeedCubit extends Cubit<FeedState> {
|
||||
|
||||
try {
|
||||
if (currentPage < lastPage) {
|
||||
print('before: $currentPage');
|
||||
currentPage++;
|
||||
print('after: $currentPage');
|
||||
final feedBlogPosts = await feedRepository.getFeedBlogPosts(
|
||||
page: currentPage,
|
||||
query: _query,
|
||||
|
||||
@@ -13,6 +13,11 @@ class RecipesCubit extends Cubit<RecipesState> {
|
||||
bool isLoading = false;
|
||||
String? _query;
|
||||
|
||||
RecipesCubit({
|
||||
required this.feedRepository,
|
||||
required this.recipeRepository,
|
||||
}) : super(const RecipesState.loading());
|
||||
|
||||
loadRecipesList({
|
||||
String? query,
|
||||
}) async {
|
||||
@@ -35,11 +40,6 @@ class RecipesCubit extends Cubit<RecipesState> {
|
||||
}
|
||||
}
|
||||
|
||||
RecipesCubit({
|
||||
required this.feedRepository,
|
||||
required this.recipeRepository,
|
||||
}) : super(const RecipesState.loading());
|
||||
|
||||
loadNextPage() async {
|
||||
if (currentPage < lastPage && !isLoading) {
|
||||
isLoading = true;
|
||||
|
||||
@@ -57,11 +57,23 @@ class _FeedScreenState extends State<FeedScreen> {
|
||||
}
|
||||
}
|
||||
|
||||
_onScrollRecipes() {}
|
||||
_onScrollRecipes() {
|
||||
if (recipesScrollController.offset >= recipesScrollController.position.maxScrollExtent && !recipesScrollController.position.outOfRange) {
|
||||
recipesCubit.loadNextPage();
|
||||
}
|
||||
}
|
||||
|
||||
_onScrollDiets() {}
|
||||
_onScrollDiets() {
|
||||
if (dietsScrollController.offset >= dietsScrollController.position.maxScrollExtent && !dietsScrollController.position.outOfRange) {
|
||||
dietsCubit.loadNextPage();
|
||||
}
|
||||
}
|
||||
|
||||
_onScrollPlans() {}
|
||||
_onScrollPlans() {
|
||||
if (plansScrollController.offset >= plansScrollController.position.maxScrollExtent && !plansScrollController.position.outOfRange) {
|
||||
// plansCubit.loadNextPage();
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
@@ -133,16 +145,17 @@ class _FeedScreenState extends State<FeedScreen> {
|
||||
},
|
||||
body: Builder(
|
||||
builder: (BuildContext context) {
|
||||
if (_selectedChipIndex == 0)
|
||||
if (_selectedChipIndex == 0) {
|
||||
return _buildAllBlogPosts();
|
||||
else if (_selectedChipIndex == 1)
|
||||
} else if (_selectedChipIndex == 1) {
|
||||
return _buildAllRecipes();
|
||||
else if (_selectedChipIndex == 2)
|
||||
} else if (_selectedChipIndex == 2) {
|
||||
return _buildDiets();
|
||||
else if (_selectedChipIndex == 3)
|
||||
} else if (_selectedChipIndex == 3) {
|
||||
return _buildPlans();
|
||||
else
|
||||
} else {
|
||||
return Center(child: Text(chipsLabelList[_selectedChipIndex]));
|
||||
}
|
||||
},
|
||||
),
|
||||
),
|
||||
@@ -274,12 +287,12 @@ class _FeedScreenState extends State<FeedScreen> {
|
||||
shrinkWrap: true,
|
||||
physics: BouncingScrollPhysics(),
|
||||
itemBuilder: (context, index) {
|
||||
return DietsWidget(diet: state.diets.data[index]);
|
||||
return DietsWidget(diet: state.dietsList[index]);
|
||||
},
|
||||
separatorBuilder: (context, index) {
|
||||
return SizedBox(height: 8);
|
||||
},
|
||||
itemCount: state.diets.data.length,
|
||||
itemCount: state.dietsList.length,
|
||||
);
|
||||
} else if (state is DietsStateError) {
|
||||
return Scaffold(
|
||||
@@ -428,6 +441,9 @@ class _FeedScreenState extends State<FeedScreen> {
|
||||
case 1:
|
||||
recipesCubit.loadRecipesList(query: query);
|
||||
break;
|
||||
case 2:
|
||||
dietsCubit.loadDiets(query: query);
|
||||
break;
|
||||
}
|
||||
},
|
||||
);
|
||||
@@ -443,6 +459,9 @@ class _FeedScreenState extends State<FeedScreen> {
|
||||
case 1:
|
||||
recipesCubit.loadRecipesList();
|
||||
break;
|
||||
case 2:
|
||||
dietsCubit.loadDiets(query: query);
|
||||
break;
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
@@ -13,20 +13,20 @@ abstract class FeedService {
|
||||
|
||||
@GET('/api/blogPosts/index')
|
||||
Future<FeedBlogPostSettingsModel> getBlogPostList({
|
||||
@Path() required int page,
|
||||
@Query('page') required int page,
|
||||
@Query('query_search') String? query,
|
||||
});
|
||||
|
||||
@GET('/api/recipes/index')
|
||||
Future<RecipesPagination> getRecipes({
|
||||
@Path() required int page,
|
||||
@Query('page') required int page,
|
||||
@Query('filters[tags][tags.id][\$in][]') required List<int>? tags,
|
||||
@Query('filters[title][\$contains]') required String? query,
|
||||
});
|
||||
|
||||
@GET('/api/diets/index')
|
||||
Future<DietsPagination> getDiets({
|
||||
@Path() required int page,
|
||||
@Query('page') required int page,
|
||||
@Query('query_search') String? query,
|
||||
});
|
||||
|
||||
|
||||
@@ -27,7 +27,10 @@ class _FeedService implements FeedService {
|
||||
String? query,
|
||||
}) async {
|
||||
final _extra = <String, dynamic>{};
|
||||
final queryParameters = <String, dynamic>{r'query_search': query};
|
||||
final queryParameters = <String, dynamic>{
|
||||
r'page': page,
|
||||
r'query_search': query,
|
||||
};
|
||||
queryParameters.removeWhere((k, v) => v == null);
|
||||
final _headers = <String, dynamic>{};
|
||||
const Map<String, dynamic>? _data = null;
|
||||
@@ -66,6 +69,7 @@ class _FeedService implements FeedService {
|
||||
}) async {
|
||||
final _extra = <String, dynamic>{};
|
||||
final queryParameters = <String, dynamic>{
|
||||
r'page': page,
|
||||
r'filters[tags][tags.id][$in][]': tags,
|
||||
r'filters[title][$contains]': query,
|
||||
};
|
||||
@@ -105,7 +109,10 @@ class _FeedService implements FeedService {
|
||||
String? query,
|
||||
}) async {
|
||||
final _extra = <String, dynamic>{};
|
||||
final queryParameters = <String, dynamic>{r'query_search': query};
|
||||
final queryParameters = <String, dynamic>{
|
||||
r'page': page,
|
||||
r'query_search': query,
|
||||
};
|
||||
queryParameters.removeWhere((k, v) => v == null);
|
||||
final _headers = <String, dynamic>{};
|
||||
const Map<String, dynamic>? _data = null;
|
||||
|
||||
@@ -345,7 +345,7 @@ class _SettingsScreenState extends State<SettingsScreen> {
|
||||
return Padding(
|
||||
padding: EdgeInsets.symmetric(horizontal: 16),
|
||||
child: InkWell(
|
||||
onTap: () {},
|
||||
onTap: () => GoRouter.of(context).pushNamed('becomeConsultantScreen'),
|
||||
borderRadius: BorderRadius.circular(20),
|
||||
child: Ink(
|
||||
height: 52,
|
||||
|
||||
Reference in New Issue
Block a user