mirror of
https://gitlab.com/comunic/comunicmobile
synced 2024-11-25 06:19:22 +00:00
Created conversation route
This commit is contained in:
parent
4be5a1b5a8
commit
1ec197202c
@ -1,4 +1,5 @@
|
|||||||
import 'package:comunic/helpers/database/conversations_database_helper.dart';
|
import 'package:comunic/helpers/database/conversations_database_helper.dart';
|
||||||
|
import 'package:comunic/helpers/users_helper.dart';
|
||||||
import 'package:comunic/lists/conversations_list.dart';
|
import 'package:comunic/lists/conversations_list.dart';
|
||||||
import 'package:comunic/lists/users_list.dart';
|
import 'package:comunic/lists/users_list.dart';
|
||||||
import 'package:comunic/models/api_request.dart';
|
import 'package:comunic/models/api_request.dart';
|
||||||
@ -22,15 +23,7 @@ class ConversationsHelper {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
ConversationsList list = ConversationsList();
|
ConversationsList list = ConversationsList();
|
||||||
response.getArray().forEach((f) => list.add(Conversation(
|
response.getArray().forEach((f) => list.add(_apiToConversation(f)));
|
||||||
id: f["ID"],
|
|
||||||
ownerID: f["ID_owner"],
|
|
||||||
lastActive: f["last_active"],
|
|
||||||
name: f["name"] == false ? null : f["name"],
|
|
||||||
following: f["following"] == 1,
|
|
||||||
sawLastMessage: f["saw_last_message"] == 1,
|
|
||||||
members: f["members"].map<int>((f) => int.parse(f)).toList(),
|
|
||||||
)));
|
|
||||||
|
|
||||||
// Update the database
|
// Update the database
|
||||||
await _conversationsDatabaseHelper.clearTable();
|
await _conversationsDatabaseHelper.clearTable();
|
||||||
@ -50,8 +43,38 @@ class ConversationsHelper {
|
|||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the name of a [conversation]. This requires information about the
|
/// Get information about a single conversation specified by its [id]
|
||||||
/// users of this conversation
|
Future<Conversation> _downloadSingle(int id) async {
|
||||||
|
try {
|
||||||
|
final response = await APIRequest(
|
||||||
|
uri: "conversations/getInfoOne",
|
||||||
|
needLogin: true,
|
||||||
|
args: {"conversationID": id.toString()}).exec();
|
||||||
|
|
||||||
|
if (response.code != 200) return null;
|
||||||
|
|
||||||
|
final conversation = _apiToConversation(response.getObject());
|
||||||
|
_conversationsDatabaseHelper.insertOrUpdate(conversation);
|
||||||
|
return conversation;
|
||||||
|
} on Exception catch (e) {
|
||||||
|
print(e.toString());
|
||||||
|
print("Could not get information about a single conversation !");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get information about a single conversation. If [force] is set to false,
|
||||||
|
/// cached version of the conversation will be used, else it will always get
|
||||||
|
/// the information from the server
|
||||||
|
Future<Conversation> getSingle(int id, {bool force = false}) async {
|
||||||
|
if(force || ! await _conversationsDatabaseHelper.has(id))
|
||||||
|
return await _downloadSingle(id);
|
||||||
|
else
|
||||||
|
return _conversationsDatabaseHelper.get(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get the name of a [conversation]. This requires information
|
||||||
|
/// about the users of this conversation
|
||||||
static String getConversationName(
|
static String getConversationName(
|
||||||
Conversation conversation, UsersList users) {
|
Conversation conversation, UsersList users) {
|
||||||
if (conversation.has_name) return conversation.name;
|
if (conversation.has_name) return conversation.name;
|
||||||
@ -69,4 +92,35 @@ class ConversationsHelper {
|
|||||||
|
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Asynchronously get the name fo the conversation
|
||||||
|
///
|
||||||
|
/// Unlike the synchronous method, this method does not need information
|
||||||
|
/// about the members of the conversation
|
||||||
|
///
|
||||||
|
/// Returns null in case of failure
|
||||||
|
static Future<String> getConversationNameAsync(
|
||||||
|
Conversation conversation) async {
|
||||||
|
if (conversation.has_name) return conversation.name;
|
||||||
|
|
||||||
|
//Get information about the members of the conversation
|
||||||
|
final members = await UsersHelper().getUsersInfo(conversation.members);
|
||||||
|
|
||||||
|
if (members == null) return null;
|
||||||
|
|
||||||
|
return ConversationsHelper.getConversationName(conversation, members);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Turn an API entry into a [Conversation] object
|
||||||
|
Conversation _apiToConversation(Map<String, dynamic> map){
|
||||||
|
return Conversation(
|
||||||
|
id: map["ID"],
|
||||||
|
ownerID: map["ID_owner"],
|
||||||
|
lastActive: map["last_active"],
|
||||||
|
name: map["name"] == false ? null : map["name"],
|
||||||
|
following: map["following"] == 1,
|
||||||
|
sawLastMessage: map["saw_last_message"] == 1,
|
||||||
|
members: map["members"].map<int>((f) => int.parse(f)).toList(),
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -40,7 +40,7 @@ class Conversation extends CacheModel implements Comparable {
|
|||||||
name = map[ConversationTableContract.C_NAME],
|
name = map[ConversationTableContract.C_NAME],
|
||||||
following = map[ConversationTableContract.C_FOLLOWING] == 1,
|
following = map[ConversationTableContract.C_FOLLOWING] == 1,
|
||||||
sawLastMessage = map[ConversationTableContract.C_SAW_LAST_MESSAGE] == 1,
|
sawLastMessage = map[ConversationTableContract.C_SAW_LAST_MESSAGE] == 1,
|
||||||
members = stringListToIntList(
|
members = listToIntList(
|
||||||
map[ConversationTableContract.C_MEMBERS].split(",")),
|
map[ConversationTableContract.C_MEMBERS].split(",")),
|
||||||
super.fromMap(map);
|
super.fromMap(map);
|
||||||
|
|
||||||
|
90
lib/ui/routes/conversation_route.dart
Normal file
90
lib/ui/routes/conversation_route.dart
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
import 'package:comunic/helpers/conversations_helper.dart';
|
||||||
|
import 'package:comunic/models/conversation.dart';
|
||||||
|
import 'package:comunic/utils/intl_utils.dart';
|
||||||
|
import 'package:comunic/utils/ui_utils.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
/// Single conversation route
|
||||||
|
///
|
||||||
|
/// @author Pierre HUBERT
|
||||||
|
|
||||||
|
class ConversationRoute extends StatefulWidget {
|
||||||
|
final int conversationID;
|
||||||
|
|
||||||
|
const ConversationRoute({
|
||||||
|
Key key,
|
||||||
|
@required this.conversationID,
|
||||||
|
}) : assert(conversationID != null),
|
||||||
|
super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<StatefulWidget> createState() => _ConversationRouteState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _ConversationRouteState extends State<ConversationRoute> {
|
||||||
|
final ConversationsHelper _conversationsHelper = ConversationsHelper();
|
||||||
|
Conversation _conversation;
|
||||||
|
String _conversationName;
|
||||||
|
bool _error = false;
|
||||||
|
|
||||||
|
setError(bool err) => setState(() => _error = err);
|
||||||
|
|
||||||
|
@override
|
||||||
|
void didChangeDependencies() {
|
||||||
|
super.didChangeDependencies();
|
||||||
|
_loadConversation();
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _loadConversation() async {
|
||||||
|
setError(false);
|
||||||
|
|
||||||
|
_conversation =
|
||||||
|
await _conversationsHelper.getSingle(widget.conversationID);
|
||||||
|
|
||||||
|
if (_conversation == null) return setError(true);
|
||||||
|
|
||||||
|
final conversationName =
|
||||||
|
await ConversationsHelper.getConversationNameAsync(_conversation);
|
||||||
|
|
||||||
|
if(conversationName == null)
|
||||||
|
return setError(true);
|
||||||
|
|
||||||
|
setState(() {
|
||||||
|
_conversationName = conversationName;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildRouteBody() {
|
||||||
|
//Handle errors
|
||||||
|
if (_error != null && _error)
|
||||||
|
return buildErrorCard(
|
||||||
|
tr("Could not get conversation information!"),
|
||||||
|
actions: <Widget>[
|
||||||
|
FlatButton(
|
||||||
|
onPressed: _loadConversation,
|
||||||
|
child: Text(
|
||||||
|
tr("Try again").toUpperCase(),
|
||||||
|
style: TextStyle(
|
||||||
|
color: Colors.white,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
|
||||||
|
//if (_conversationName == null || _conversation == null)
|
||||||
|
return buildCenteredProgressBar();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Scaffold(
|
||||||
|
appBar: AppBar(
|
||||||
|
title: Text(
|
||||||
|
_conversationName == null ? tr("Loading") : _conversationName,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
body: _buildRouteBody(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
import 'package:comunic/ui/screens/conversations_screen.dart';
|
import 'package:comunic/ui/screens/conversations_list_screen.dart';
|
||||||
import 'package:comunic/ui/screens/menus_screen.dart';
|
import 'package:comunic/ui/screens/menus_screen.dart';
|
||||||
import 'package:comunic/ui/tiles/custom_bottom_navigation_bar_item.dart';
|
import 'package:comunic/ui/tiles/custom_bottom_navigation_bar_item.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
@ -49,7 +49,7 @@ class _HomeRouteState extends State<HomeRoute> {
|
|||||||
Widget _buildBody(BuildContext context) {
|
Widget _buildBody(BuildContext context) {
|
||||||
switch (_currTab) {
|
switch (_currTab) {
|
||||||
case 0:
|
case 0:
|
||||||
return ConversationsScreen();
|
return ConversationsListScreen();
|
||||||
|
|
||||||
case 1:
|
case 1:
|
||||||
return MenuScreen();
|
return MenuScreen();
|
||||||
|
@ -2,6 +2,7 @@ import 'package:comunic/enums/load_error_level.dart';
|
|||||||
import 'package:comunic/helpers/conversations_helper.dart';
|
import 'package:comunic/helpers/conversations_helper.dart';
|
||||||
import 'package:comunic/helpers/users_helper.dart';
|
import 'package:comunic/helpers/users_helper.dart';
|
||||||
import 'package:comunic/lists/conversations_list.dart';
|
import 'package:comunic/lists/conversations_list.dart';
|
||||||
|
import 'package:comunic/ui/routes/conversation_route.dart';
|
||||||
import 'package:comunic/ui/tiles/conversation_tile.dart';
|
import 'package:comunic/ui/tiles/conversation_tile.dart';
|
||||||
import 'package:comunic/utils/intl_utils.dart';
|
import 'package:comunic/utils/intl_utils.dart';
|
||||||
import 'package:comunic/utils/ui_utils.dart';
|
import 'package:comunic/utils/ui_utils.dart';
|
||||||
@ -11,12 +12,12 @@ import 'package:flutter/material.dart';
|
|||||||
///
|
///
|
||||||
/// @author Pierre HUBERT
|
/// @author Pierre HUBERT
|
||||||
|
|
||||||
class ConversationsScreen extends StatefulWidget {
|
class ConversationsListScreen extends StatefulWidget {
|
||||||
@override
|
@override
|
||||||
State<StatefulWidget> createState() => _ConversationScreenState();
|
State<StatefulWidget> createState() => _ConversationScreenState();
|
||||||
}
|
}
|
||||||
|
|
||||||
class _ConversationScreenState extends State<ConversationsScreen> {
|
class _ConversationScreenState extends State<ConversationsListScreen> {
|
||||||
final ConversationsHelper _conversationsHelper = ConversationsHelper();
|
final ConversationsHelper _conversationsHelper = ConversationsHelper();
|
||||||
final UsersHelper _usersHelper = UsersHelper();
|
final UsersHelper _usersHelper = UsersHelper();
|
||||||
ConversationsList _list;
|
ConversationsList _list;
|
||||||
@ -88,6 +89,13 @@ class _ConversationScreenState extends State<ConversationsScreen> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Open a conversation
|
||||||
|
void _openConversation(BuildContext context, int conversationId){
|
||||||
|
Navigator.of(context).push(MaterialPageRoute(builder: (c){
|
||||||
|
return ConversationRoute(conversationID: conversationId,);
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
if (_error == LoadErrorLevel.MAJOR) return _buildErrorCard();
|
if (_error == LoadErrorLevel.MAJOR) return _buildErrorCard();
|
||||||
@ -103,10 +111,12 @@ class _ConversationScreenState extends State<ConversationsScreen> {
|
|||||||
),
|
),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: ListView.builder(
|
child: ListView.builder(
|
||||||
|
controller: ScrollController(),
|
||||||
itemBuilder: (context, index) {
|
itemBuilder: (context, index) {
|
||||||
return ConversationTile(
|
return ConversationTile(
|
||||||
conversation: _list.elementAt(index),
|
conversation: _list.elementAt(index),
|
||||||
usersList: _list.users,
|
usersList: _list.users,
|
||||||
|
onOpen: (c){_openConversation(context, c.id);},
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
itemCount: _list.length,
|
itemCount: _list.length,
|
@ -9,14 +9,21 @@ import 'package:flutter/material.dart';
|
|||||||
///
|
///
|
||||||
/// @author Pierre HUBERT
|
/// @author Pierre HUBERT
|
||||||
|
|
||||||
|
typedef OpenConversationCallback = void Function(Conversation);
|
||||||
|
|
||||||
class ConversationTile extends StatelessWidget {
|
class ConversationTile extends StatelessWidget {
|
||||||
final Conversation conversation;
|
final Conversation conversation;
|
||||||
final UsersList usersList;
|
final UsersList usersList;
|
||||||
|
final OpenConversationCallback onOpen;
|
||||||
|
|
||||||
const ConversationTile(
|
const ConversationTile(
|
||||||
{Key key, @required this.conversation, @required this.usersList})
|
{Key key,
|
||||||
|
@required this.conversation,
|
||||||
|
@required this.usersList,
|
||||||
|
@required this.onOpen})
|
||||||
: assert(conversation != null),
|
: assert(conversation != null),
|
||||||
assert(usersList != null),
|
assert(usersList != null),
|
||||||
|
assert(onOpen != null),
|
||||||
super(key: key);
|
super(key: key);
|
||||||
|
|
||||||
_buildSubInformation(IconData icon, String content) {
|
_buildSubInformation(IconData icon, String content) {
|
||||||
@ -35,6 +42,7 @@ class ConversationTile extends StatelessWidget {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return ListTile(
|
return ListTile(
|
||||||
|
onTap: () => onOpen(conversation),
|
||||||
// Conversation name
|
// Conversation name
|
||||||
title: Text(
|
title: Text(
|
||||||
ConversationsHelper.getConversationName(
|
ConversationsHelper.getConversationName(
|
||||||
|
@ -2,8 +2,8 @@
|
|||||||
///
|
///
|
||||||
/// @author Pierre HUBERT
|
/// @author Pierre HUBERT
|
||||||
|
|
||||||
/// Transform a list of string into something else
|
/// Transform a list of dynamic thins into something a list of ints
|
||||||
List<int> stringListToIntList(List<String> srcList){
|
List<int> listToIntList(List<dynamic> srcList){
|
||||||
List<int> list = List();
|
List<int> list = List();
|
||||||
|
|
||||||
srcList.forEach((e){
|
srcList.forEach((e){
|
||||||
|
Loading…
Reference in New Issue
Block a user