import 'package:comunic/enums/load_error_level.dart'; import 'package:comunic/helpers/conversations_helper.dart'; import 'package:comunic/helpers/users_helper.dart'; import 'package:comunic/lists/conversations_list.dart'; import 'package:comunic/models/conversation.dart'; import 'package:comunic/ui/routes/conversation_route.dart'; import 'package:comunic/ui/routes/create_conversation_route.dart'; import 'package:comunic/ui/routes/update_conversation_route.dart'; import 'package:comunic/ui/tiles/conversation_tile.dart'; import 'package:comunic/utils/intl_utils.dart'; import 'package:comunic/utils/ui_utils.dart'; import 'package:flutter/material.dart'; /// Conversations screen /// /// @author Pierre HUBERT class ConversationsListScreen extends StatefulWidget { @override State createState() => _ConversationScreenState(); } class _ConversationScreenState extends State { final ConversationsHelper _conversationsHelper = ConversationsHelper(); final UsersHelper _usersHelper = UsersHelper(); ConversationsList _list; LoadErrorLevel _error = LoadErrorLevel.NONE; bool _loading = true; @override void didChangeDependencies() { super.didChangeDependencies(); _loadConversations(); } @override void setState(fn) { if(mounted) super.setState(fn); } void setError(LoadErrorLevel err) => setState(() => _error = err); void setLoading(bool loading) => setState(() => _loading = loading); /// Get the list of conversations, once from the cache, once from the server Future _loadConversations() async { await _loadConversationsList(true); await _loadConversationsList(false); } void _gotLoadingError() { setLoading(false); setError(_list == null ? LoadErrorLevel.MAJOR : LoadErrorLevel.MINOR); } /// Load the list of conversations Future _loadConversationsList(bool cached) async { setError(LoadErrorLevel.NONE); setLoading(true); //Get the list of conversations var list; if (cached) list = await _conversationsHelper.getCachedList(); else list = await _conversationsHelper.downloadList(); if (list == null) return _gotLoadingError(); //Get information about the members of the conversations list.users = await _usersHelper.getUsersInfo(list.allUsersID); if (list.users == null) return _gotLoadingError(); //Save list setState(() { _list = list; }); setLoading(false); } /// Build an error card Widget _buildErrorCard() { return buildErrorCard( tr("Could not retrieve the list of conversations!"), actions: [ FlatButton( onPressed: () => _loadConversationsList(false), child: Text( tr("Retry").toUpperCase(), style: TextStyle( color: Colors.white, ), ), ) ], ); } /// Open a conversation void _openConversation(BuildContext context, int conversationId) { Navigator.of(context).push(MaterialPageRoute(builder: (c) { return ConversationRoute( conversationID: conversationId, ); })); } /// Create a new conversation void _createConversation(BuildContext context) { Navigator.of(context) .push(MaterialPageRoute(builder: (c) => CreateConversationRoute())); } /// Handle conversations updated requests void _updateConversation(Conversation conversation) { Navigator.of(context).push( MaterialPageRoute( builder: (c) => UpdateConversationRoute( conversationID: conversation.id, ), ), ); } /// Handle conversation deletion request Future _requestDeleteConversation(Conversation conversation) async { final result = await showDialog( context: context, builder: (c) { return AlertDialog( title: Text(tr("Delete conversation")), content: Text(tr( "Do you really want to remove this conversation from your list of conversations ? If you are the owner of this conversation, it will be completely deleted!")), actions: [ FlatButton( onPressed: () => Navigator.pop(context, false), child: Text(tr("cancel").toUpperCase()), ), FlatButton( onPressed: () => Navigator.pop(context, true), child: Text( tr("delete").toUpperCase(), style: TextStyle(color: Colors.red), ), ) ], ); }, ); if (result == null || !result) return; // Request the conversation to be deleted now if (!await _conversationsHelper.deleteConversation(conversation.id)) Scaffold.of(context).showSnackBar( SnackBar(content: Text(tr("Could not delete the conversation!")))); // Reload the list of conversations _loadConversationsList(false); } @override Widget build(BuildContext context) { if (_error == LoadErrorLevel.MAJOR) return _buildErrorCard(); if (_list == null) return buildCenteredProgressBar(); // Show the list of conversations return Stack( children: [ Column( children: [ Container( child: _error == LoadErrorLevel.MINOR ? _buildErrorCard() : null, ), Expanded( child: ListView.builder( controller: ScrollController(), itemBuilder: (context, index) { return ConversationTile( conversation: _list.elementAt(index), usersList: _list.users, onOpen: (c) { _openConversation(context, c.id); }, onRequestUpdate: _updateConversation, onRequestDelete: _requestDeleteConversation, ); }, itemCount: _list.length, ), ), ], ), // Add conversation button Positioned( right: 20.0, bottom: 20.0, child: FloatingActionButton( onPressed: () => _createConversation(context), child: Icon(Icons.add), ), ), // Loading indicator Positioned( top: 8.0, left: 0.0, right: 0.0, child: Container( child: !_loading ? null : Center( child: CircularProgressIndicator(), ), ), ) ], ); } }