shows a loading indicator when loading.

This commit is contained in:
Faris Armoush
2025-06-22 12:46:17 +03:00
parent 8494f0a8f1
commit b79ab06d95
4 changed files with 39 additions and 22 deletions

View File

@ -14,7 +14,7 @@ final class DebouncedCommunitiesService implements CommunitiesService {
final Duration debounceDuration; final Duration debounceDuration;
Timer? _debounceTimer; Timer? _debounceTimer;
Completer<CommunitiesPaginationModel>? _completer; late Completer<CommunitiesPaginationModel>? _completer;
@override @override
Future<CommunitiesPaginationModel> getCommunity( Future<CommunitiesPaginationModel> getCommunity(
@ -22,10 +22,6 @@ final class DebouncedCommunitiesService implements CommunitiesService {
) async { ) async {
_debounceTimer?.cancel(); _debounceTimer?.cancel();
if (_completer != null && !_completer!.isCompleted) {
_completer!.completeError(Exception('Request cancelled by newer request'));
}
_completer = Completer<CommunitiesPaginationModel>(); _completer = Completer<CommunitiesPaginationModel>();
final currentCompleter = _completer!; final currentCompleter = _completer!;

View File

@ -24,9 +24,13 @@ class CommunitiesBloc extends Bloc<CommunitiesEvent, CommunitiesState> {
Emitter<CommunitiesState> emit, Emitter<CommunitiesState> emit,
) async { ) async {
try { try {
emit(state.copyWith(status: CommunitiesStatus.loading)); emit(
state.copyWith(status: CommunitiesStatus.loading),
);
final paginationResponse = await _communitiesService.getCommunity(event.param); final paginationResponse = await _communitiesService.getCommunity(
event.param,
);
emit( emit(
CommunitiesState( CommunitiesState(
@ -35,6 +39,7 @@ class CommunitiesBloc extends Bloc<CommunitiesEvent, CommunitiesState> {
hasNext: paginationResponse.hasNext, hasNext: paginationResponse.hasNext,
currentPage: paginationResponse.page, currentPage: paginationResponse.page,
searchQuery: event.param.search, searchQuery: event.param.search,
isLoadingMore: false,
), ),
); );
} on APIException catch (e) { } on APIException catch (e) {
@ -65,6 +70,7 @@ class CommunitiesBloc extends Bloc<CommunitiesEvent, CommunitiesState> {
emit( emit(
state.copyWith( state.copyWith(
status: CommunitiesStatus.success,
communities: updatedCommunities, communities: updatedCommunities,
hasNext: paginationResponse.hasNext, hasNext: paginationResponse.hasNext,
currentPage: paginationResponse.page, currentPage: paginationResponse.page,
@ -84,6 +90,7 @@ class CommunitiesBloc extends Bloc<CommunitiesEvent, CommunitiesState> {
) { ) {
emit( emit(
state.copyWith( state.copyWith(
status: CommunitiesStatus.failure,
isLoadingMore: false, isLoadingMore: false,
errorMessage: e.message, errorMessage: e.message,
), ),
@ -93,6 +100,7 @@ class CommunitiesBloc extends Bloc<CommunitiesEvent, CommunitiesState> {
void _onError(Object e, Emitter<CommunitiesState> emit) { void _onError(Object e, Emitter<CommunitiesState> emit) {
emit( emit(
state.copyWith( state.copyWith(
status: CommunitiesStatus.failure,
isLoadingMore: false, isLoadingMore: false,
errorMessage: e.toString(), errorMessage: e.toString(),
), ),

View File

@ -42,11 +42,9 @@ class _SpaceManagementCommunitiesTreeState
} }
void _onSearchChanged(String searchQuery) { void _onSearchChanged(String searchQuery) {
context.read<CommunitiesBloc>().add( context
LoadCommunities(LoadCommunitiesParam( .read<CommunitiesBloc>()
search: searchQuery.trim(), .add(LoadCommunities(LoadCommunitiesParam(search: searchQuery.trim())));
)),
);
} }
void _onLoadMore() { void _onLoadMore() {
@ -80,6 +78,13 @@ class _SpaceManagementCommunitiesTreeState
CommunitiesStatus.success => _buildCommunitiesTree(context, state), CommunitiesStatus.success => _buildCommunitiesTree(context, state),
CommunitiesStatus.failure => _buildErrorState(context, state), CommunitiesStatus.failure => _buildErrorState(context, state),
}, },
Visibility(
visible: state.isLoadingMore,
child: const Padding(
padding: EdgeInsets.all(8.0),
child: Center(child: CircularProgressIndicator()),
),
),
], ],
), ),
); );
@ -132,14 +137,24 @@ class _SpaceManagementCommunitiesTreeState
} }
return Expanded( return Expanded(
child: SpaceManagementSidebarCommunitiesList( child: Stack(
communities: state.communities, children: [
onLoadMore: state.hasNext ? _onLoadMore : null, SpaceManagementSidebarCommunitiesList(
isLoadingMore: state.isLoadingMore, communities: state.communities,
hasNext: state.hasNext, onLoadMore: state.hasNext ? _onLoadMore : null,
itemBuilder: (context, index) { isLoadingMore: state.isLoadingMore,
return _buildCommunityTile(context, state.communities[index]); hasNext: state.hasNext,
}, itemBuilder: (context, index) {
return _buildCommunityTile(context, state.communities[index]);
},
),
if (state.status == CommunitiesStatus.loading &&
state.communities.isNotEmpty)
ColoredBox(
color: Colors.white.withValues(alpha: 0.7),
child: const Center(child: CircularProgressIndicator()),
),
],
), ),
); );
} }

View File

@ -37,7 +37,6 @@ class _SpaceManagementSidebarCommunitiesListState
void _onScroll() { void _onScroll() {
if (_scrollController.position.pixels >= if (_scrollController.position.pixels >=
_scrollController.position.maxScrollExtent - 100) { _scrollController.position.maxScrollExtent - 100) {
// Trigger pagination when user is close to the bottom
if (widget.hasNext && !widget.isLoadingMore && widget.onLoadMore != null) { if (widget.hasNext && !widget.isLoadingMore && widget.onLoadMore != null) {
widget.onLoadMore!(); widget.onLoadMore!();
} }
@ -67,7 +66,6 @@ class _SpaceManagementSidebarCommunitiesListState
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
// Calculate item count including loading indicator
final itemCount = widget.communities.length + (widget.isLoadingMore ? 1 : 0); final itemCount = widget.communities.length + (widget.isLoadingMore ? 1 : 0);
return SingleChildScrollView( return SingleChildScrollView(