2019-04-23 12:35:41 +00:00
import ' package:comunic/enums/load_error_level.dart ' ;
import ' package:comunic/helpers/conversations_helper.dart ' ;
2020-04-18 12:33:07 +00:00
import ' package:comunic/helpers/events_helper.dart ' ;
2019-04-23 15:29:58 +00:00
import ' package:comunic/helpers/users_helper.dart ' ;
import ' package:comunic/lists/conversations_list.dart ' ;
2019-05-01 08:52:10 +00:00
import ' package:comunic/models/conversation.dart ' ;
2020-05-05 11:21:37 +00:00
import ' package:comunic/ui/routes/main_route/main_route.dart ' ;
2019-05-01 08:58:45 +00:00
import ' package:comunic/ui/routes/update_conversation_route.dart ' ;
2020-04-16 12:58:02 +00:00
import ' package:comunic/ui/screens/create_conversation_screen.dart ' ;
2019-04-23 12:35:41 +00:00
import ' package:comunic/ui/tiles/conversation_tile.dart ' ;
2020-04-18 12:33:07 +00:00
import ' package:comunic/ui/widgets/safe_state.dart ' ;
2019-04-23 12:35:41 +00:00
import ' package:comunic/utils/intl_utils.dart ' ;
import ' package:comunic/utils/ui_utils.dart ' ;
import ' package:flutter/material.dart ' ;
/// Conversations screen
///
/// @author Pierre HUBERT
2019-04-24 15:46:25 +00:00
class ConversationsListScreen extends StatefulWidget {
2020-05-09 05:10:18 +00:00
final bool useSmallFAB ;
2020-05-09 05:28:17 +00:00
final Function ( ) onOpen ;
2020-05-09 05:10:18 +00:00
2020-05-09 05:28:17 +00:00
const ConversationsListScreen ( {
Key key ,
this . useSmallFAB = false ,
this . onOpen ,
} ) : assert ( useSmallFAB ! = null ) ,
2020-05-09 05:10:18 +00:00
super ( key: key ) ;
2019-04-23 12:35:41 +00:00
@ override
State < StatefulWidget > createState ( ) = > _ConversationScreenState ( ) ;
}
2020-04-18 12:33:07 +00:00
class _ConversationScreenState extends SafeState < ConversationsListScreen > {
2019-04-23 12:35:41 +00:00
final ConversationsHelper _conversationsHelper = ConversationsHelper ( ) ;
2019-04-23 15:29:58 +00:00
final UsersHelper _usersHelper = UsersHelper ( ) ;
ConversationsList _list ;
2019-04-23 12:35:41 +00:00
LoadErrorLevel _error = LoadErrorLevel . NONE ;
2019-05-04 07:21:40 +00:00
final GlobalKey < RefreshIndicatorState > _refreshIndicatorKey =
GlobalKey < RefreshIndicatorState > ( ) ;
2019-04-23 12:35:41 +00:00
@ override
2020-04-18 12:33:07 +00:00
void initState ( ) {
super . initState ( ) ;
this . listen < NewNumberUnreadConversations > (
2020-05-05 11:21:37 +00:00
( d ) = > _refreshIndicatorKey . currentState . show ( ) ) ;
2019-04-23 12:35:41 +00:00
}
2019-05-01 15:10:23 +00:00
@ override
2020-04-18 12:33:07 +00:00
void didChangeDependencies ( ) {
super . didChangeDependencies ( ) ;
_loadConversations ( ) ;
2019-05-01 15:10:23 +00:00
}
2019-04-23 12:35:41 +00:00
void setError ( LoadErrorLevel err ) = > setState ( ( ) = > _error = err ) ;
2019-04-24 13:03:36 +00:00
/// Get the list of conversations, once from the cache, once from the server
Future < void > _loadConversations ( ) async {
await _loadConversationsList ( true ) ;
await _loadConversationsList ( false ) ;
}
2019-04-23 15:29:58 +00:00
void _gotLoadingError ( ) {
2019-04-23 12:35:41 +00:00
setError ( _list = = null ? LoadErrorLevel . MAJOR : LoadErrorLevel . MINOR ) ;
}
/// Load the list of conversations
2019-04-24 13:03:36 +00:00
Future < void > _loadConversationsList ( bool cached ) async {
2019-04-23 12:35:41 +00:00
setError ( LoadErrorLevel . NONE ) ;
2019-04-24 13:03:36 +00:00
//Get the list of conversations
var list ;
2019-04-27 14:23:08 +00:00
if ( cached )
2019-04-24 13:03:36 +00:00
list = await _conversationsHelper . getCachedList ( ) ;
else
list = await _conversationsHelper . downloadList ( ) ;
2019-04-23 15:29:58 +00:00
if ( list = = null ) return _gotLoadingError ( ) ;
2019-04-23 12:35:41 +00:00
2019-04-23 15:29:58 +00:00
//Get information about the members of the conversations
2019-04-24 09:33:58 +00:00
list . users = await _usersHelper . getUsersInfo ( list . allUsersID ) ;
2019-05-01 15:10:23 +00:00
2019-04-24 13:03:36 +00:00
if ( list . users = = null ) return _gotLoadingError ( ) ;
2019-04-23 12:35:41 +00:00
//Save list
2019-04-23 15:29:58 +00:00
setState ( ( ) {
_list = list ;
} ) ;
2019-04-23 12:35:41 +00:00
}
/// Build an error card
Widget _buildErrorCard ( ) {
return buildErrorCard (
tr ( " Could not retrieve the list of conversations! " ) ,
actions: < Widget > [
FlatButton (
2019-05-04 07:21:40 +00:00
onPressed: ( ) = > _refreshIndicatorKey . currentState . show ( ) ,
2019-04-23 12:35:41 +00:00
child: Text (
tr ( " Retry " ) . toUpperCase ( ) ,
style: TextStyle (
color: Colors . white ,
) ,
) ,
)
] ,
) ;
}
2019-04-24 15:46:25 +00:00
/// Open a conversation
2020-04-16 12:58:02 +00:00
void _openConversation ( int conversationId ) {
2020-04-17 13:26:37 +00:00
MainController . of ( context ) . openConversation ( conversationId ) ;
2020-05-09 05:28:17 +00:00
if ( widget . onOpen ! = null ) widget . onOpen ( ) ;
2019-04-24 15:46:25 +00:00
}
2019-04-27 14:23:08 +00:00
/// Create a new conversation
2020-04-16 12:58:02 +00:00
void _createConversation ( ) {
2020-04-17 13:26:37 +00:00
MainController . of ( context ) . push ( CreateConversationScreen ( ) ) ;
2019-04-27 14:23:08 +00:00
}
2019-05-01 08:58:45 +00:00
/// Handle conversations updated requests
void _updateConversation ( Conversation conversation ) {
2020-04-17 13:26:37 +00:00
MainController . of ( context ) . push (
2020-04-16 12:58:02 +00:00
UpdateConversationRoute (
conversationID: conversation . id ,
2019-05-01 08:58:45 +00:00
) ,
) ;
}
/// Handle conversation deletion request
2019-05-01 08:52:10 +00:00
Future < void > _requestDeleteConversation ( Conversation conversation ) async {
final result = await showDialog < bool > (
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: < Widget > [
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 ) ;
}
2019-04-23 12:35:41 +00:00
@ override
Widget build ( BuildContext context ) {
if ( _error = = LoadErrorLevel . MAJOR ) return _buildErrorCard ( ) ;
if ( _list = = null ) return buildCenteredProgressBar ( ) ;
// Show the list of conversations
2019-04-24 13:03:36 +00:00
return Stack (
children: < Widget > [
Column (
children: < Widget > [
Container (
child: _error = = LoadErrorLevel . MINOR ? _buildErrorCard ( ) : null ,
) ,
Expanded (
2019-05-04 07:21:40 +00:00
child: RefreshIndicator (
onRefresh: ( ) = > _loadConversationsList ( false ) ,
key: _refreshIndicatorKey ,
child: ListView . builder (
physics: AlwaysScrollableScrollPhysics ( ) ,
controller: ScrollController ( ) ,
itemBuilder: ( context , index ) {
return ConversationTile (
conversation: _list . elementAt ( index ) ,
usersList: _list . users ,
onOpen: ( c ) {
2020-04-16 12:58:02 +00:00
_openConversation ( c . id ) ;
2019-05-04 07:21:40 +00:00
} ,
onRequestUpdate: _updateConversation ,
onRequestDelete: _requestDeleteConversation ,
) ;
} ,
itemCount: _list . length ,
) ,
2019-04-24 13:03:36 +00:00
) ,
) ,
] ,
) ,
2019-04-27 14:23:08 +00:00
// Add conversation button
Positioned (
2020-05-09 05:10:18 +00:00
right: widget . useSmallFAB ? 5.0 : 20.0 ,
bottom: widget . useSmallFAB ? 5.0 : 20.0 ,
2019-04-27 14:23:08 +00:00
child: FloatingActionButton (
2020-05-09 05:10:18 +00:00
mini: widget . useSmallFAB ,
2020-04-16 12:58:02 +00:00
onPressed: ( ) = > _createConversation ( ) ,
2019-04-27 14:23:08 +00:00
child: Icon ( Icons . add ) ,
) ,
) ,
2019-04-24 13:03:36 +00:00
] ,
2019-04-23 12:35:41 +00:00
) ;
}
}