flutter doesn't load more users don't know why - flutter

So I'm trying to load more users with pagination, it should only show 20 users and load new ones when the end of the screen is reached, but widget.loadMoreEndOfScroll gets returned null when it shouldn't, I don't know what else could be wrong, other times it worked a few times and than it stopped working and only showing 20 instead of loading new ones.
so this is the class what I use
class CAScaffold extends StatefulWidget {
const CAScaffold({
Key? key,
this.canLoadMoreEndOfScroll,
this.loadMoreEndOfScroll,
}) : super(key: key);
final bool? canLoadMoreEndOfScroll;
final Function? loadMoreEndOfScroll;
#override
State<CAScaffold> createState() => _CAScaffoldState();
}
this is the listener below
class _CAScaffoldState extends State<CAScaffold> {
ScrollController scrollUsersController = ScrollController();
final GlobalKey<ScaffoldState> _key = GlobalKey();
#override
void initState() {
scrollUsersController.addListener(() {
if(scrollUsersController.offset >= scrollUsersController.position.maxScrollExtent &&
!scrollUsersController.position.outOfRange &&
widget.canLoadMoreEndOfScroll != null && widget.canLoadMoreEndOfScroll!) {
print('endofscroll ${widget.loadMoreEndOfScroll}');
if(widget.loadMoreEndOfScroll != null) {
print('loadMoreEndOfScroll ${widget.loadMoreEndOfScroll}');
widget.loadMoreEndOfScroll!();
}
}
});
super.initState();
}
here it gets called and will call the getAllUsers function
#override
Widget build(BuildContext context) {
return CAScaffold(
canLoadMoreEndOfScroll: loadingUsers == false && allUsersLoaded == false,
loadMoreEndOfScroll: () {
getAllUsers();
newSearch = false;
},
pageTitle: 'Accounts',
child: Column(
children: <Widget>[
BlocConsumer<AccountScreenCubit, AccountScreenState>(
listener: (context, state) {
if(state is AccountScreenLoadingUsersState) {
loadingUsers = true;
}
if(state is AccountScreenUsersError) {
loadingUsers = false;
}
if(state is AccountScreenUsersLoaded) {
users.addAll(state.users);
print(state.users.length);
loadingUsers = false;
if(state.users.isEmpty) {
allUsersLoaded = true;
}
}
},
getAllUsers function
void getAllUsers() {
if(loadingUsers == false && allUsersLoaded == false) {
context.read<AccountScreenCubit>().getUsers(
searchTerm: searchInput,
orderFilter: dropDownValue,
newSearch: newSearch,
);
}
}
and than it gets send to the cubit
class AccountScreenCubit extends Cubit<AccountScreenState> {
AccountScreenCubit() : super(AccountScreenInitial());
QuerySnapshot? lastDocument;
Future<void> getUsers({String? searchTerm, bool newSearch = true, String? orderFilter}) async {
if(newSearch){
lastDocument = null;
}
try {
emit(AccountScreenLoadingUsersState());
await FirestoreUserHelper.getAllUsersOrderedByName(
20,
searchTerm: searchTerm,
orderFilter: orderFilter,
lastSnapshot: lastDocument,
).then((FirestoreReturn value) {
if(value.success) {
if(value.snapshot != null) {
lastDocument = value.snapshot;
}
emit(AccountScreenUsersLoaded(users: value.returnMain));
} else {
emit(AccountScreenUsersError(errorMsg: value.errorMessage));
}
});
} catch(e) {
emit(AccountScreenUsersError(errorMsg: 'Something went wrong: $e'));
}
}
}
if there is something I have missed let me know

You are not calling the getAllUsers function because you forgot the brackets, so add them.
loadMoreEndOfScroll: () {
getAllUsers();
newSearch = false;
},
You probably have to put CAScaffold inside BlocConsumer, otherwise parameter canLoadMoreEndOfScroll: loadingUsers == false && allUsersLoaded == false, is never updated.

Related

How to update difference Time using Provider on flutter?

I have class:
class JWSModel extends ChangeNotifier {
String ketCounterShalat = "";
String diff = "";
void streamDifferentTime() {
DateTime now = DateTime.now();
if (now.isBefore(dhuhrTime) && now.isAfter(_dhuha)) {
ketCounterShalat = "Menuju dhuhur";
diff = now.difference(dhuhrTime).toString();
} else if (now.isBefore(asrTime) && now.isAfter(dhuhrTime)) {
ketCounterShalat = "Menuju ashar";
diff = now.difference(asrTime).toString();
} else if (now.isBefore(maghribTime) && now.isAfter(asrTime)) {
ketCounterShalat = "Menuju maghrib";
diff = now.difference(maghribTime).toString();
} else if (now.isBefore(ishaTime) && now.isAfter(maghribTime)) {
ketCounterShalat = "Menuju isya";
diff = now.difference(ishaTime).toString();
} else if (now.isBefore(sunriseTime) && now.isAfter(fajrTime)) {
diff = now.difference(sunriseTime).toString();
ketCounterShalat = "Menuju terbit";
} else if (now.isBefore(_dhuha) && now.isAfter(sunriseTime)) {
diff = now.difference(_dhuha).toString();
ketCounterShalat = "Menuju dhuha";
} else {
if (fajrTime.day == now.day) {
diff = now.difference(fajrTime).toString();
} else if (fajrTime.day != now.day) {
diff = now.difference(fajrTime.add(const Duration(days: 1))).toString();
}
ketCounterShalat = "Menuju subuh";
notifyListeners();
}
String get counterShalat => diff;
String get ketCounter => ketCounterShalat;
}
next, in the widget I created
class JWS extends StatefulWidget {
const JWS({Key? key}) : super(key: key);
#override
State<JWS> createState() => _JWSState();
}
class _JWSState extends State<JWS> {
JWSModel jws = JWSModel();
Future<void> getJWS() async {
jws.init();
}
#override
void initState() {
super.initState();
getJWS();
Timer.periodic(const Duration(seconds: 1), (timer) {
jws.streamDifferentTime();
});
}
#override
Widget build(BuildContext context) {
final state = context.watch<JWSModel>();
log(state.counterShalat);
Why not success? I want to update difference Time, I use a timer to update it. I don't want to use setState({}); because I think it will be hard to update every 1 second.
Update: if i log in class JWSModel success.
But, i call in class JWS nothing appears.
i want to get update different time but I don't want to use setState({});
or is there the right code for me to use.
class _JWSState extends State<JWS> {
#override
void initState() {
super.initState();
Timer.periodic(const Duration(seconds: 1), (timer) {
context.read<JWSModel>().streamDifferentTime();
});
}
#override
Widget build(BuildContext context) {
final state = context.watch<JWSModel>();
return Scaffold ( appBar: AppBar(),
body: Text(state.counterShalat,
style:TextStyle(color:Colors.blue)),
);
}
when any update from notifylistener, the value should be updated too.

Where to prevent re-animation of ListView.builder items when scrolling back to previously animated items?

I have a listview in which the text of items are animated when they first appear - and when they reappear after enough scrolling. When the list grows to certain size and the user scrolls back far enough items are animated again - presumably they've been removed from the widget tree and are now being re-inserted and thus get re-initiated etc. I want to prevent this from happening so that they only animate the first time they appear.
I think this means I need to have state stored somewhere per item that keeps track and tells the individual items whether they should animate on them being built or not. I am not sure where to put and how to connect that though, partly because it seems to overlap between presentation and business logic layers. I think perhaps it should be a variable in the list items contained in the list object that the listview builder is constructing from - or should it somehow be in the actual widgets in the listview?
class _StockListViewBuilderState extends State<StockListViewBuilder> with asc_alertBar {
final ScrollController _scrollController = ScrollController();
late double _scrollPosition;
late double _maxScrollExtent;
late bool isThisTheEnd = false;
_scrollListener() async {
setState(() {
_scrollPosition = _scrollController.position.pixels;
_maxScrollExtent = _scrollController.position.maxScrollExtent;
});
if (!isThisTheEnd && _scrollPosition / _maxScrollExtent > 0.90) {
isThisTheEnd = true;
if (widget.stockListicle.getIsRemoteEmpty()) {
alertBar('No more items available', /* null,*/ context: context);
} else {
await widget.stockListicle.fetch(numberToFetch: 5);
}
}
if (isThisTheEnd && _scrollPosition / _maxScrollExtent <= 0.90) {
isThisTheEnd = false;
}
}
#override
void initState() {
super.initState();
late String? userFullName = GetIt.I.get<Authenticate>().user?.fullName;
developer.log('Authenticated user $userFullName', name: '_StockListViewBuilderState');
developer.log("init ", name: "_StockListViewBuilderState ");
int listCount;
_scrollController.addListener(_scrollListener);
WidgetsBinding.instance.addPostFrameCallback((_) async {
//developer.log("stckLtcl init pf con ");
listCount = widget.stockListicle.items.length;
if (listCount < 10 && !widget.stockListicle.getIsRemoteEmpty()) {
try {
await widget.stockListicle.fetch(numberToFetch: 10);
} catch (e) {
super.setState(() {
//developer.log("Can't load stock:$e");
alertBar(
"Couldn't load from the internet.",
context: context,
backgroundColor: Colors.purple,
);
});
}
}
});
WidgetsBinding.instance.addPostFrameCallback((_) async {
final ConnectionNotifier connectionNotifier = context.read<ConnectionNotifier>();
if (connectionNotifier.isConnected() != true) {
await connectionNotifier.check();
if (connectionNotifier.isConnected() != true) {
alertBar("Please check the internet connection.", context: context);
}
}
});
}
#override
Widget build(BuildContext context) {
return ListView.builder(
scrollDirection: Axis.vertical,
controller: _scrollController,
shrinkWrap: true,
key: widget.theKey,
itemCount: widget.stockListicle.items.length + 1,
itemBuilder: (context, index) {
if (index <= widget.stockListicle.items.length - 1) {
return InkWell(
onTap: (() => Navigator.pushNamed(
context,
'/stocks/stock',
arguments: ScreenArguments(widget.stockListicle.items[index] as Stock),
)),
child: StockListItem(
stock: widget.stockListicle.items[index] as Stock,
));
} else {
return LoadingItemNotifier(
isLoading: widget.stockListicle.getIsBusyLoading(),
);
}
},
);
}
}
//...
Currently StockListItem extends StatelessWidget and returns a 'ListTile' which as its title parameter has ...title: AnimatedText(textContent: stock.title),...
I was trying to keep track of first-time-animation inside AnimatedText widget until I realized from an OOP & Flutter perspective, it's probably wrong place...
class AnimatedText extends StatefulWidget {
final bool doShowMe;
final String textContent;
final Duration hideDuration;
final double durationFactor;
const AnimatedText({
Key? key,
this.doShowMe = true,
this.textContent = '',
this.hideDuration = const Duration(milliseconds: 500),
this.durationFactor = 1,
}) : super(key: key);
#override
State<AnimatedText> createState() => _AnimatedTextState();
}
class _AnimatedTextState extends State<AnimatedText> with SingleTickerProviderStateMixin {
late AnimationController _appearanceController;
late String displayText;
late String previousText;
late double durationFactor;
late Duration buildDuration = Duration(
milliseconds: (widget.textContent.length / 15 * widget.durationFactor * 1000).round());
#override
void initState() {
super.initState();
developer.log('init ${widget.textContent}', name: '_AnimatedTextState');
displayText = '';
previousText = widget.textContent;
_appearanceController = AnimationController(
vsync: this,
duration: buildDuration,
)..addListener(
() => updateText(),
);
if (widget.doShowMe) {
_doShowMe();
}
}
void updateText() {
String payload = widget.textContent;
int numCharsToShow = (_appearanceController.value * widget.textContent.length).ceil();
if (widget.doShowMe) {
// make it grow
displayText = payload.substring(0, numCharsToShow);
// developer.log('$numCharsToShow / ${widget.textContent.length} ${widget.textContent}');
} else {
// make it shrink
displayText = payload.substring(payload.length - numCharsToShow, payload.length);
}
}
#override
void didUpdateWidget(AnimatedText oldWidget) {
super.didUpdateWidget(oldWidget);
if ((widget.doShowMe != oldWidget.doShowMe) || (widget.textContent != oldWidget.textContent)) {
if (widget.doShowMe) {
_doShowMe();
} else {
_doHideMe();
}
}
if (widget.doShowMe && widget.textContent != previousText) {
previousText = widget.textContent;
developer.log('reset');
_appearanceController
..reset()
..forward();
}
}
#override
void dispose() {
_appearanceController.dispose();
displayText = '';
super.dispose();
}
#override
Widget build(BuildContext context) {
return AnimatedBuilder(
animation: _appearanceController,
builder: (context, child) {
return Text(displayText);
});
}
void _doShowMe() {
_appearanceController
..duration = buildDuration
..forward();
}
void _doHideMe() {
_appearanceController
..duration = widget.hideDuration
..reverse();
}
}

Flutter - How to play a sequence of videos one after another?

How can I play a sequence of videos one after another with no breaks in between and no user action - just show videos one right after the other? (efficiently)
Here is what I tried:
VideoPlayer:
class MyVideoPlayer extends StatefulWidget {
MyVideoPlayer({
Key? key,
required this.onComplete,
}) : super(key: key);
final VoidCallback onComplete;
#override
MyVideoPlayerState createState() => MyVideoPlayerState();
}
class MyVideoPlayerState extends State<MyVideoPlayer> {
#override
void initState() {
super.initState();
controller.addListener(() {
if (!controller.value.isPlaying &&
controller.value.position.inSeconds >=
controller.value.duration.inSeconds) {
widget.onComplete();
}
});
}
#override
Widget build(BuildContext context) {
return VideoPlayer(
controller,
);
}
}
Main:
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MyVideoPlayer(
onComplete: () {
_playVideo(asset);
},
);
}
}
_playVideo(String asset) {
controller =
VideoPlayerController.asset(asset);
controller.addListener(() {
setState(() {});
if (!controller.value.isPlaying &&
controller.value.position.inSeconds >=
controller.value.duration.inSeconds) {
}
});
controller.initialize().then((_) {
setState(() {});
controller.play();
if (mounted) setState(() {});
});
setState(() {
});
}
But onComplete gets accessed only after the first video and then no more. It should be called after each video is finished.
Any way of solving this will help a lot.
You can play multiple video by creating list of videos at initstate or in seperate datamodel and then changing the index of list to the controller.
this method also have some issue as mentioned in this question link
void playVideo() async {
if (DateTime.now().isAfter(videoData[index].start_from) &&
DateTime.now().isBefore(videoData[index].end_on)) {
bool played_count = await CountQuery().whenComplete(() {
});
file = File(videoData[index].file_link);
if (file.existsSync() && !played_count) {
isEnd = true;
controller = VideoPlayerController.file(file)
..initialize().then((value) {
setState(() {
controller.play();
});
controller.addListener(() {
// checking the duration and position every time
// Video Completed//
if (controller.value.duration == controller.value.position &&
isEnd) {
setState(() {
isEnd = false;
});
CreateLog("video");
controller.dispose();
PlayNext();
}
});
})
..setLooping(false);
} else {
PlayNext();
}
} else {
PlayNext();
}
}
void PlayNext() {
setState(() {
index++;
if (videoData.length > index) {
// this.asset = videoData[index].file_link;
this.file = File(videoData[index].file_link);
playVideo();
} else {
index = 0;
// this.asset = videoData[index].file_link;
this.file = File(videoData[index].file_link);
playVideo();
}
});
}

when I am calling the provider in the inistate return data got null

My question is.......When the app Started(initial start) circular progress indicator appears & didn't got any data.....My app has 3 tabs(using tabbar), but when I swicth between my tabs & when I came to the Home tab now I got the data & ui render according to the data....
I want when the app start get data & needs render the data....
Ui inistate
class Home extends StatefulWidget {
const Home({ Key? key }) : super(key: key);
#override
_HomeState createState() => _HomeState();
}
class _HomeState extends State<Home> {
int _page = 1;
void initState() {
var postProvider = Provider.of<PostProvider>(context, listen: false);
postProvider.initStreamsPost();
postProvider.fetchAllData(_page);
}
#override
Widget build(BuildContext context) {
return Consumer<PostProvider>(builder: (context, postsModel, child) {
print("builder length... ${postsModel.allData!.length}"); //when the first time app opens what I got print in terminal => builder length... 0
if (postsModel.allData != null && postsModel.allData!.length > 0) {
return ListView.builder(
physics: const AlwaysScrollableScrollPhysics(),
itemCount: postsModel.allData?.length,
itemBuilder: (BuildContext context, int index) {
return PostCard(
);
});
}
return Center(child: CircularProgressIndicator());
}
}
}
changeNotifier class
class PostProvider extends ChangeNotifier {
int totalPages = 0;
int? get totalRecords => _postsFetcher!.totalPosts;
PostApi? _postApi;
PostsModel? _postsFetcher;
List<Post>? get allData =>
_postsFetcher?.posts != null ? _postsFetcher?.posts : [];
PostProvider() {
initStreamsPost();
}
initStreamsPost() async {
_postApi = await new PostApi();
_postsFetcher = await new PostsModel();
}
fetchAllData(pageNumber) async {
if ((totalPages == 0) || pageNumber <= totalPages) {
PostsModel itemModel = await _postApi!.getPost2(pageNumber);
print("have data");
if (_postsFetcher!.posts == null) {
totalPages = ((itemModel.totalPosts! - 1) / 4).ceil();
_postsFetcher = itemModel;
notifyListeners();
} else {
_postsFetcher?.posts?.addAll(itemModel.posts!);
_postsFetcher = _postsFetcher;
notifyListeners();
}
}
}
}
While using Provider in initState, prefer using it this way:
void initState() {
WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
var postProvider = Provider.of<PostProvider>(context, listen: false);
postProvider.initStreamsPost();
postProvider.fetchAllData(_page);
});
}

Flutter bloc - Event only gets called 2 times inside the bloc logic

I'm having problems to send the event in the bloc. The problem I'm having is that when I send the first event the Bloc is getting called and after I recall it again with a diferrent tab and it works, but when I change to another tab the bloc doesn't get called even if the add event is sending. I have checked with the debbuger and when I call it after the 2 first it doesn't get executed the bloc.
Example where I send the event:
class ListOpportunitiesList extends StatefulWidget {
final String title;
final bool showTopIcons, showFilterMarvTypes;
final OpportunitiesListTypeEnum opportunitiesListTypeEnum;
const ListOpportunitiesList({
Key key,
#required this.title,
#required this.showTopIcons,
#required this.showFilterMarvTypes,
#required this.opportunitiesListTypeEnum,
}) : super(key: key);
#override
_ListOpportunitiesListState createState() => _ListOpportunitiesListState();
}
class _ListOpportunitiesListState extends State<ListOpportunitiesList> {
InvestmentMarvTypeEnum _investmentMarvTypeEnum;
InvestmentStatusEnum _investmentStatusEnum;
InvestmentOpportunityBloc investmentOpportunityBloc;
#override
void initState() {
super.initState();
investmentOpportunityBloc = getIt.getItInstance<InvestmentOpportunityBloc>();
this.getOpportunities();
}
// Calling the event works only the first 2 times
void getOpportunities() {
investmentOpportunityBloc.add(
InvestmentOpportunityLoadEvent(
opportunitiesListTypeEnum: this.widget.opportunitiesListTypeEnum,
investmentMarvTypeEnum: this._investmentMarvTypeEnum,
investmentStatusEnum: this._investmentStatusEnum,
),
);
}
#override
void dispose() {
super.dispose();
this.investmentOpportunityBloc?.close();
}
#override
Widget build(BuildContext context) {
final double height = MediaQuery.of(context).size.height;
final double topMargin = this.widget.showFilterMarvTypes
? height * UIConstants.marginTopPercentageWithFilter
: height * UIConstants.marginTopPercentage;
return BlocProvider<InvestmentOpportunityBloc>(
create: (context) => this.investmentOpportunityBloc,
child: ListView(
padding: EdgeInsets.zero,
children: [
CustomAppBar(
title: '${this.widget.title}',
showLogged: this.widget.showTopIcons,
),
Visibility(
visible: this.widget.opportunitiesListTypeEnum == OpportunitiesListTypeEnum.all,
child: SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Row(
children: InvestmentMarvTypeEnum.values
.map(
(e) => SelectableRoundedRectangleButton(
onPressed: () {
setState(() {
this._investmentMarvTypeEnum =
this._investmentMarvTypeEnum == e ? null : e;
});
this.getOpportunities();
},
selected: e == this._investmentMarvTypeEnum,
text:
'${InvestmentOpportunityUtility.getMarvTypeString(e)}',
),
)
.toList(),
),
),
),
BlocBuilder<InvestmentOpportunityBloc, InvestmentOpportunityState>(
builder: (context, state) {
if (state is InvestmentOpportunityLoaded) {
if (state.investmentOpportunityModel.isNotEmpty) {
return Column(
children: [
for (InvestmentOpportunityModel opportunity
in state.investmentOpportunityModel)
InvestmentOpportunityCard(
investmentOpportunityModel: opportunity,
),
Visibility(
visible: !state.hasReachedMax,
child: ListBottomLoadingWidget(),
),
],
);
} else {
return AppEmptyWidget(
investmentMarvTypeEnum: this._investmentMarvTypeEnum,
topMargin: topMargin,
uiEmptyTypeEnum: UIEmptyTypeEnum.investment_opportunity,
);
}
} else if (state is InvestmentOpportunityError) {
return AppErrorWidget(
topMargin: topMargin,
apiNetworkException: state.apiError,
retryButton: () => this.getOpportunities(),
);
} else {
return AppLoadingWidget(
topMargin: topMargin,
);
}
},
),
],
),
);
}
}
Here is the bloc logic:
class InvestmentOpportunityBloc
extends Bloc<InvestmentOpportunityEvent, InvestmentOpportunityState> {
final GetInvestmentOpportunities getInvestmentOpportunities;
final GetInvestedInvestmentOpportunities getInvestedInvestmentOpportunities;
final GetFavorites getFavorites;
List<InvestmentOpportunityModel> listOpportunity;
InvestmentOpportunityBloc({
#required this.getInvestmentOpportunities,
#required this.getInvestedInvestmentOpportunities,
#required this.getFavorites,
}) : super(InvestmentOpportunityInitial());
#override
Stream<InvestmentOpportunityState> mapEventToState(
InvestmentOpportunityEvent event,
) async* {
final currentState = state;
if (event is InvestmentOpportunityLoadEvent || event is InvestmentOpportunityChangeTab) {
bool modifyType = false;
if (currentState is InvestmentOpportunityLoaded) {
switch ((event as InvestmentOpportunityLoadEvent).opportunitiesListTypeEnum) {
case OpportunitiesListTypeEnum.invested:
{
modifyType = (event as InvestmentOpportunityLoadEvent).investmentStatusEnum !=
currentState
.investmentsOpportunitiesInvestedDTO.investmentStatusEnum;
}
break;
case OpportunitiesListTypeEnum.all:
{
modifyType = (event as InvestmentOpportunityLoadEvent).investmentMarvTypeEnum !=
currentState.investmentOpportunityDTO.investmentMarvTypeEnum;
}
break;
}
if (!modifyType && this._hasReachedMax(currentState)) {
return;
}
}
InvestmentsOpportunitiesInvestedDTO investmentsOpportunitiesInvestedDTO;
InvestmentOpportunityDTO investmentOpportunityDTO;
Either<ApiNetworkException, List<InvestmentOpportunityModel>>
opportunityEither;
switch ((event as InvestmentOpportunityLoadEvent).opportunitiesListTypeEnum) {
case OpportunitiesListTypeEnum.invested:
{
if (currentState is InvestmentOpportunityLoaded && !modifyType) {
currentState.investmentsOpportunitiesInvestedDTO.pageDTO
.incrementPage();
investmentsOpportunitiesInvestedDTO =
currentState.investmentsOpportunitiesInvestedDTO;
} else {
yield InvestmentOpportunityInitial();
investmentsOpportunitiesInvestedDTO =
InvestmentsOpportunitiesInvestedDTO(
pageDTO: PageDTO(),
investmentStatusEnum: (event as InvestmentOpportunityLoadEvent).investmentStatusEnum,
);
}
opportunityEither = await this.getInvestedInvestmentOpportunities(
investmentsOpportunitiesInvestedDTO);
}
break;
case OpportunitiesListTypeEnum.all:
{
if (currentState is InvestmentOpportunityLoaded && !modifyType) {
currentState.investmentOpportunityDTO.pageDTO.incrementPage();
investmentOpportunityDTO = currentState.investmentOpportunityDTO;
} else {
yield InvestmentOpportunityInitial();
investmentOpportunityDTO = InvestmentOpportunityDTO(
pageDTO: PageDTO(),
investmentMarvTypeEnum: (event as InvestmentOpportunityLoadEvent).investmentMarvTypeEnum,
);
}
opportunityEither =
await this.getInvestmentOpportunities(investmentOpportunityDTO);
}
break;
}
yield opportunityEither.fold(
(error) => InvestmentOpportunityError(error),
(opportunities) {
if (currentState is InvestmentOpportunityLoaded &&
opportunities.isEmpty) {
return currentState.copyWith(hasReachedMax: true);
}
this.listOpportunity = currentState is InvestmentOpportunityLoaded && !modifyType
? currentState.investmentOpportunityModel + opportunities
: opportunities;
return InvestmentOpportunityLoaded(
investmentOpportunityModel: this.listOpportunity,
investmentOpportunityDTO: investmentOpportunityDTO,
investmentsOpportunitiesInvestedDTO:
investmentsOpportunitiesInvestedDTO,
hasReachedMax: BlocUtility.hasReachedMax(
opportunities.length,
investmentsOpportunitiesInvestedDTO != null
? investmentsOpportunitiesInvestedDTO.pageDTO.take
: investmentOpportunityDTO.pageDTO.take,
),
);
},
);
} else if (event is InvestmentOpportunityUpdateStatusOfInvestment &&
currentState is InvestmentOpportunityLoaded) {
currentState.investmentOpportunityModel[currentState
.investmentOpportunityModel
.indexOf(event.investmentOpportunityModel)] =
event.investmentOpportunityModel;
yield currentState.copyWith(
investmentOpportunityModel: currentState.investmentOpportunityModel,
);
}
}
bool _hasReachedMax(InvestmentOpportunityState state) {
return state is InvestmentOpportunityLoaded && state.hasReachedMax;
}
}