diff --git a/covas_mobile/lib/pages/ListItemMenu.dart b/covas_mobile/lib/pages/ListItemMenu.dart index 5ffa41d..0f02b1b 100644 --- a/covas_mobile/lib/pages/ListItemMenu.dart +++ b/covas_mobile/lib/pages/ListItemMenu.dart @@ -48,6 +48,9 @@ class ListItemMenu extends StatefulWidget { class _MyHomePageState extends State { BannerAd? _bannerAd; final AuthService _authService = AuthService(); + late ScrollController _scrollController; + int _fetchCount = 0; + bool _isLoading = false; Future> postsFuture = getPosts(); List filteredPosts = []; @@ -144,6 +147,46 @@ class _MyHomePageState extends State { return "${year}-${month}-${day}"; } + void _incrementFetchCount() { + setState(() { + _fetchCount++; + }); + } + + void _decrementFetchCount() { + setState(() { + if (_fetchCount > 0 && filteredPosts.isNotEmpty) { + _fetchCount--; + } + }); + } + + void _scrollListener() { + if (_scrollController.position.pixels == + _scrollController.position.maxScrollExtent) { + _incrementFetchCount(); + } else if (_scrollController.position.pixels == + _scrollController.position.minScrollExtent) { + _decrementFetchCount(); + } + _fetchData(); + } + + Future _fetchData() async { + print("Counter : ${_fetchCount}"); + if (_isLoading) return; + setState(() { + _isLoading = true; + }); + + await Future.delayed(Duration(seconds: 2)); + fetchPostsByLocation(); + + setState(() { + _isLoading = false; + }); + } + @override void initState() { super.initState(); @@ -153,10 +196,19 @@ class _MyHomePageState extends State { _bannerAd = ad; }); }); + _scrollController = ScrollController(); + _scrollController.addListener(_scrollListener); + // Initialize data fetch when the page loads _getCurrentLocation(); } + @override + void dispose() { + _scrollController.dispose(); + super.dispose(); + } + // Get the device's current location Future _getCurrentLocation() async { PermissionStatus status = await Permission.location.status; @@ -347,7 +399,8 @@ class _MyHomePageState extends State { queryParameters = dateParameter; } - return Uri.parse("${globals.api}/$endpoint?$queryParameters"); + return Uri.parse( + "${globals.api}/$endpoint?$queryParameters&skip=${_fetchCount}"); } Future searchSuggestionsByItem(String input) async { @@ -770,12 +823,22 @@ class _MyHomePageState extends State { } return ListView.separated( - itemCount: displayedPosts.length, + controller: _scrollController, + itemCount: displayedPosts.isNotEmpty + ? displayedPosts.length + + (_isLoading ? 1 : 0) // Add 1 only if loading + : 0, itemBuilder: (context, index) { + if (index >= displayedPosts.length) { + return _isLoading + ? Center(child: CircularProgressIndicator()) + : SizedBox.shrink(); + } final post = displayedPosts[index]; final startDate = DateTime.parse(post.startDate!); final date = DateFormat.yMd().format(startDate); final time = DateFormat.Hm().format(startDate); + return ListTile( title: Text('${post.name!}'), subtitle: Text('${post.place!}\n${date} ${time}'), diff --git a/covas_mobile/pubspec.lock b/covas_mobile/pubspec.lock index f8e2f6c..770d04a 100644 --- a/covas_mobile/pubspec.lock +++ b/covas_mobile/pubspec.lock @@ -13,10 +13,10 @@ packages: dependency: transitive description: name: args - sha256: bf9f5caeea8d8fe6721a9c358dd8a5c1947b27f1cfaa18b39c301273594919e6 + sha256: d0481093c50b1da8910eb0bb301626d4d8eb7284aa739614d2b394ee09e3ea04 url: "https://pub.dev" source: hosted - version: "2.6.0" + version: "2.7.0" asn1lib: dependency: transitive description: