1
0
mirror of https://gitlab.com/comunic/comunicmobile synced 2024-11-22 21:09:21 +00:00
comunicmobile/lib/ui/widgets/posts_list_widget.dart

172 lines
4.4 KiB
Dart

import 'package:comunic/helpers/groups_helper.dart';
import 'package:comunic/helpers/users_helper.dart';
import 'package:comunic/lists/groups_list.dart';
import 'package:comunic/lists/posts_list.dart';
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';
/// Posts list widget
///
/// Displays a list of posts
///
/// @author Pierre HUBERT
class PostsListWidget extends StatefulWidget {
final Future<PostsList> Function() getPostsList;
final Future<PostsList> Function(int from) getOlder;
final bool showPostsTarget;
final bool buildListView;
final bool userNamesClickable;
const PostsListWidget({
Key key,
@required this.getPostsList,
@required this.showPostsTarget,
this.userNamesClickable = true,
this.buildListView = true,
this.getOlder,
}) : assert(getPostsList != null),
assert(showPostsTarget != null),
assert(buildListView != null),
assert(userNamesClickable != null),
super(key: key);
@override
State<StatefulWidget> createState() => PostsListWidgetState();
}
class PostsListWidgetState extends State<PostsListWidget> {
// Helpers
final UsersHelper _usersHelper = UsersHelper();
final GroupsHelper _groupsHelper = GroupsHelper();
// Class members
PostsList _list;
UsersList _users;
GroupsList _groups;
ScrollWatcher _scrollController;
ErrorLevel _error = ErrorLevel.NONE;
bool _loading = false;
set error(ErrorLevel err) => setState(() => _error = err);
@override
void initState() {
super.initState();
_scrollController = ScrollWatcher(onReachBottom: reachedPostsBottom);
}
@override
void didChangeDependencies() {
super.didChangeDependencies();
_loadPostsList();
}
void _loadError() {
error = _list == null ? ErrorLevel.MAJOR : ErrorLevel.MINOR;
_loading = false;
}
/// Load the list of posts
Future<void> _loadPostsList({bool getOlder = false}) async {
if (_loading) return;
_loading = true;
final list = !getOlder
? await widget.getPostsList()
: await widget.getOlder(_list.oldestID);
if (list == null) return _loadError();
final users = await _usersHelper.getList(list.usersID);
if (users == null) return _loadError();
final groups = await _groupsHelper.getList(list.groupsID);
if (groups == null) return _loadError();
if (!mounted) return;
setState(() {
if (!getOlder) {
_list = list;
_users = users;
_groups = groups;
} else {
_list.addAll(list);
_users.addAll(users);
_groups.addAll(groups);
}
});
_loading = false;
}
Widget _buildErrorCard() {
return buildErrorCard(tr("Could not get the list of posts !"));
}
Widget _buildNoPostNotice() {
return Center(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Text(tr("There is no post to display here yet.")),
),
);
}
Widget _buildListView() {
return RefreshIndicator(
child: ListView.builder(
itemCount: _list.length,
itemBuilder: _buildItem,
controller: _scrollController,
),
onRefresh: () => _loadPostsList(),
);
}
Widget _buildColumn() {
return Column(
children: List.generate(
_list.length,
(i) => _buildItem(null, i),
),
);
}
Widget _buildItem(BuildContext context, int index) {
return PostTile(
post: _list[index],
usersInfo: _users,
groupsInfo: _groups,
onDeletedPost: _removePost,
showPostTarget: widget.showPostsTarget,
userNamesClickable: widget.userNamesClickable,
);
}
@override
Widget build(BuildContext context) {
if (_error == ErrorLevel.MAJOR) return _buildErrorCard();
if (_list == null) return buildCenteredProgressBar();
if (_list.length == 0) return _buildNoPostNotice();
return widget.buildListView ? _buildListView() : _buildColumn();
}
void _removePost(Post post) => setState(() => _list.remove(post));
void reachedPostsBottom() {
if (widget.getOlder != null) _loadPostsList(getOlder: true);
}
}