diff --git a/lib/helpers/posts_helper.dart b/lib/helpers/posts_helper.dart index 76352c7..2aed37c 100644 --- a/lib/helpers/posts_helper.dart +++ b/lib/helpers/posts_helper.dart @@ -39,12 +39,13 @@ const _APIUserAccessMap = { class PostsHelper { /// Get the list of latest posts. Return the list of posts or null in case of /// failure - Future getLatest() async { + Future getLatest({int from = 0}) async { final response = await APIRequest( uri: "posts/get_latest", needLogin: true, args: { - "include_groups": true.toString() + "include_groups": true.toString(), + "startFrom": from.toString(), } ).exec(); diff --git a/lib/lists/posts_list.dart b/lib/lists/posts_list.dart index cbc484e..32a2c0e 100644 --- a/lib/lists/posts_list.dart +++ b/lib/lists/posts_list.dart @@ -46,4 +46,12 @@ class PostsList extends ListBase { return set; } + + /// Get the ID of the oldest post of this list. Returns 0 if the list is empty + int get oldestID { + if(isEmpty) + return 0; + + return this.elementAt(length - 1).id; + } } diff --git a/lib/ui/screens/newest_posts.dart b/lib/ui/screens/newest_posts.dart index 2aebf3d..0577fc5 100644 --- a/lib/ui/screens/newest_posts.dart +++ b/lib/ui/screens/newest_posts.dart @@ -20,6 +20,7 @@ class _NewestPostsScreenState extends State { Widget build(BuildContext context) { return PostsListWidget( getPostsList: _postsHelper.getLatest, + getOlder: (f) => _postsHelper.getLatest(from: f - 1), showPostsTarget: true, ); } diff --git a/lib/ui/widgets/posts_list_widget.dart b/lib/ui/widgets/posts_list_widget.dart index 01be463..9bff3a8 100644 --- a/lib/ui/widgets/posts_list_widget.dart +++ b/lib/ui/widgets/posts_list_widget.dart @@ -6,6 +6,7 @@ import 'package:comunic/lists/users_list.dart'; import 'package:comunic/models/post.dart'; import 'package:comunic/ui/screens/conversation_screen.dart'; import 'package:comunic/ui/tiles/post_tile.dart'; +import 'package:comunic/ui/widgets/scroll_watcher.dart'; import 'package:comunic/utils/intl_utils.dart'; import 'package:comunic/utils/ui_utils.dart'; import 'package:flutter/material.dart'; @@ -18,6 +19,7 @@ import 'package:flutter/material.dart'; class PostsListWidget extends StatefulWidget { final Future Function() getPostsList; + final Future Function(int from) getOlder; final bool showPostsTarget; final bool buildListView; final bool userNamesClickable; @@ -28,6 +30,7 @@ class PostsListWidget extends StatefulWidget { @required this.showPostsTarget, this.userNamesClickable = true, this.buildListView = true, + this.getOlder, }) : assert(getPostsList != null), assert(showPostsTarget != null), assert(buildListView != null), @@ -47,10 +50,17 @@ class _PostsListWidgetState extends State { PostsList _list; UsersList _users; GroupsList _groups; + ScrollWatcher _scrollController; + ErrorLevel _error = ErrorLevel.NONE; set error(ErrorLevel err) => setState(() => _error = err); - ErrorLevel _error = ErrorLevel.NONE; + @override + void initState() { + super.initState(); + + _scrollController = ScrollWatcher(onReachBottom: _reachedPostsBottom); + } @override void didChangeDependencies() { @@ -62,8 +72,10 @@ class _PostsListWidgetState extends State { error = _list == null ? ErrorLevel.MAJOR : ErrorLevel.MINOR; /// Load the list of posts - Future _loadPostsList() async { - final list = await widget.getPostsList(); + Future _loadPostsList({bool getOlder = false}) async { + final list = !getOlder + ? await widget.getPostsList() + : await widget.getOlder(_list.oldestID); if (list == null) return _loadError(); @@ -76,9 +88,15 @@ class _PostsListWidgetState extends State { if (groups == null) return _loadError(); setState(() { - _list = list; - _users = users; - _groups = groups; + if (!getOlder) { + _list = list; + _users = users; + _groups = groups; + } else { + _list.addAll(list); + _users.addAll(users); + _groups.addAll(groups); + } }); } @@ -99,6 +117,7 @@ class _PostsListWidgetState extends State { return ListView.builder( itemCount: _list.length, itemBuilder: _buildItem, + controller: _scrollController, ); } @@ -131,4 +150,8 @@ class _PostsListWidgetState extends State { } void _removePost(Post post) => setState(() => _list.remove(post)); + + void _reachedPostsBottom() { + if (widget.getOlder != null) _loadPostsList(getOlder: true); + } }