From eb34ed5c3d67b3890da012a7c2a28ac90358ef52 Mon Sep 17 00:00:00 2001 From: Pierre HUBERT Date: Wed, 24 Apr 2019 14:25:46 +0200 Subject: [PATCH] Store locally the list of conversations --- lib/helpers/conversations_helper.dart | 15 +++++--- .../conversations_database_helper.dart | 20 +++++++++++ lib/helpers/database/database_contract.dart | 12 +++++++ lib/helpers/database/database_helper.dart | 24 +++++++++++-- .../database/model_database_helper.dart | 20 +++++++---- lib/models/conversation.dart | 34 ++++++++++++++++--- lib/utils/list_utils.dart | 14 ++++++++ 7 files changed, 121 insertions(+), 18 deletions(-) create mode 100644 lib/helpers/database/conversations_database_helper.dart create mode 100644 lib/utils/list_utils.dart diff --git a/lib/helpers/conversations_helper.dart b/lib/helpers/conversations_helper.dart index 6990930..3757997 100644 --- a/lib/helpers/conversations_helper.dart +++ b/lib/helpers/conversations_helper.dart @@ -1,3 +1,4 @@ +import 'package:comunic/helpers/database/conversations_database_helper.dart'; import 'package:comunic/lists/conversations_list.dart'; import 'package:comunic/lists/users_list.dart'; import 'package:comunic/models/api_request.dart'; @@ -9,6 +10,9 @@ import 'package:comunic/utils/account_utils.dart'; /// @author Pierre HUBERT class ConversationsHelper { + final ConversationsDatabaseHelper _conversationsDatabaseHelper = + ConversationsDatabaseHelper(); + /// Download the list of conversations from the server Future downloadList() async { final response = @@ -28,6 +32,10 @@ class ConversationsHelper { members: f["members"].map((f) => int.parse(f)).toList(), ))); + // Update the database + await _conversationsDatabaseHelper.clearTable(); + await _conversationsDatabaseHelper.insertAll(list); + return list; } on Exception catch (e) { print(e.toString()); @@ -46,14 +54,11 @@ class ConversationsHelper { for (int i = 0; i < 3 && i < conversation.members.length; i++) if (conversation.members[i] != userID()) { name += (count > 0 ? ", " : "") + - users - .getUser(conversation.members[i]) - .fullName; + users.getUser(conversation.members[i]).fullName; count++; } - if(conversation.members.length > 3) - name += ", ..."; + if (conversation.members.length > 3) name += ", ..."; return name; } diff --git a/lib/helpers/database/conversations_database_helper.dart b/lib/helpers/database/conversations_database_helper.dart new file mode 100644 index 0000000..84b51ea --- /dev/null +++ b/lib/helpers/database/conversations_database_helper.dart @@ -0,0 +1,20 @@ +import 'package:comunic/helpers/database/database_contract.dart'; +import 'package:comunic/helpers/database/model_database_helper.dart'; +import 'package:comunic/models/conversation.dart'; + +/// Conversations database helper +/// +/// @author Pierre HUBERT + +class ConversationsDatabaseHelper extends ModelDatabaseHelper { + @override + Conversation initializeFromMap(Map map) { + return Conversation.fromMap(map); + } + + @override + String tableName() { + return ConversationTableContract.TABLE_NAME; + } + +} \ No newline at end of file diff --git a/lib/helpers/database/database_contract.dart b/lib/helpers/database/database_contract.dart index 4885bd9..871d084 100644 --- a/lib/helpers/database/database_contract.dart +++ b/lib/helpers/database/database_contract.dart @@ -22,4 +22,16 @@ abstract class UserTableContract { static const C_VISIBILITY = "visibility"; static const C_VIRTUAL_DIRECTORY = "virtual_directory"; static const C_ACCOUNT_IMAGE_URL = "account_image_url"; +} + +/// Conversations table contract +abstract class ConversationTableContract { + static const TABLE_NAME = "conversations"; + static const C_ID = BaseTableContract.C_ID; + static const C_OWNER_ID = "owner_id"; + static const C_LAST_ACTIVE = "last_active"; + static const C_NAME = "name"; + static const C_FOLLOWING = "following"; + static const C_SAW_LAST_MESSAGE = "saw_last_message"; + static const C_MEMBERS = "members"; } \ No newline at end of file diff --git a/lib/helpers/database/database_helper.dart b/lib/helpers/database/database_helper.dart index 14c7ac5..94589eb 100644 --- a/lib/helpers/database/database_helper.dart +++ b/lib/helpers/database/database_helper.dart @@ -34,7 +34,14 @@ abstract class DatabaseHelper { /// Currently : delete all the database tables and initialize it again static Future _performDatabaseUpdate( Database db, int oldVersion, int newVersion) async { - //Initialize database again + // Drop users table + await db.execute("DROP TABLE IF EXISTS ${UserTableContract.TABLE_NAME}"); + + // Drop conversations table + await db + .execute("DROP TABLE IF EXISTS ${ConversationTableContract.TABLE_NAME}"); + + // Initialize database again await _initializeDatabase(db, newVersion); } @@ -45,9 +52,20 @@ abstract class DatabaseHelper { "${UserTableContract.C_ID} INTEGER PRIMARY KEY, " "${UserTableContract.C_FIRST_NAME} TEXT, " "${UserTableContract.C_LAST_NAME} TEXT, " - "${UserTableContract.C_VISIBILITY} TEXT," - "${UserTableContract.C_VIRTUAL_DIRECTORY} TEXT," + "${UserTableContract.C_VISIBILITY} TEXT, " + "${UserTableContract.C_VIRTUAL_DIRECTORY} TEXT, " "${UserTableContract.C_ACCOUNT_IMAGE_URL} TEXT" ")"); + + //Create conversations table + await db.execute("CREATE TABLE ${ConversationTableContract.TABLE_NAME} (" + "${ConversationTableContract.C_ID} INTEGER PRIMARY KEY, " + "${ConversationTableContract.C_OWNER_ID} INTEGER, " + "${ConversationTableContract.C_LAST_ACTIVE} INTEGER, " + "${ConversationTableContract.C_NAME} TEXT, " + "${ConversationTableContract.C_FOLLOWING} INTEGER, " + "${ConversationTableContract.C_SAW_LAST_MESSAGE} INTEGER, " + "${ConversationTableContract.C_MEMBERS} TEXT" + ")"); } } diff --git a/lib/helpers/database/model_database_helper.dart b/lib/helpers/database/model_database_helper.dart index 547e10c..1410bdd 100644 --- a/lib/helpers/database/model_database_helper.dart +++ b/lib/helpers/database/model_database_helper.dart @@ -9,7 +9,6 @@ import 'package:comunic/models/cache_model.dart'; /// @author Pierre HUBERT abstract class ModelDatabaseHelper { - /// Get the name of the target table. Must be specified by the children /// of this class String tableName(); @@ -19,8 +18,7 @@ abstract class ModelDatabaseHelper { /// Insert an entry in the database Future _insertDB(T el) async { - await (await DatabaseHelper.get()) - .insert(tableName(), el.toMap()); + await (await DatabaseHelper.get()).insert(tableName(), el.toMap()); } /// Update an element in the database @@ -48,6 +46,11 @@ abstract class ModelDatabaseHelper { return null; } + /// Empty the table + Future clearTable() async { + await (await DatabaseHelper.get()).execute("DELETE FROM ${tableName()}"); + } + /// Check out whether an element specified with its [id] is present /// or not in the local database Future has(int id) async { @@ -65,8 +68,13 @@ abstract class ModelDatabaseHelper { /// Insert or update an important amount of elements Future insertOrUpdateAll(List list) async { - for(int i = 0; i < list.length; i++) - await insertOrUpdate(list[i]); + for (int i = 0; i < list.length; i++) await insertOrUpdate(list[i]); } -} \ No newline at end of file + /// Insert an important amount of elements + /// + /// This might throw if there are conflicting IDs + Future insertAll(List list) async { + for (T el in list) await _insertDB(el); + } +} diff --git a/lib/models/conversation.dart b/lib/models/conversation.dart index 992191c..a8caa2a 100644 --- a/lib/models/conversation.dart +++ b/lib/models/conversation.dart @@ -1,11 +1,13 @@ +import 'package:comunic/helpers/database/database_contract.dart'; +import 'package:comunic/models/cache_model.dart'; +import 'package:comunic/utils/list_utils.dart'; import 'package:meta/meta.dart'; /// Conversation model /// /// @author Pierre HUBERT -class Conversation { - final int id; +class Conversation extends CacheModel { final int ownerID; final int lastActive; final String name; @@ -14,7 +16,7 @@ class Conversation { final List members; const Conversation({ - @required this.id, + @required int id, @required this.ownerID, @required this.lastActive, @required this.name, @@ -26,8 +28,32 @@ class Conversation { assert(lastActive != null), assert(following != null), assert(sawLastMessage != null), - assert(members != null); + assert(members != null), + super(id: id); /// Check out whether a conversation has a fixed name or not bool get has_name => this.name != null; + + Conversation.fromMap(Map map) + : ownerID = map[ConversationTableContract.C_OWNER_ID], + lastActive = map[ConversationTableContract.C_LAST_ACTIVE], + name = map[ConversationTableContract.C_NAME], + following = map[ConversationTableContract.C_FOLLOWING] == 1, + sawLastMessage = map[ConversationTableContract.C_SAW_LAST_MESSAGE] == 1, + members = stringListToIntList( + map[ConversationTableContract.C_MEMBERS].split(",")), + super.fromMap(map); + + @override + Map toMap() { + return { + ConversationTableContract.C_ID: id, + ConversationTableContract.C_OWNER_ID: ownerID, + ConversationTableContract.C_LAST_ACTIVE: lastActive, + ConversationTableContract.C_NAME: name, + ConversationTableContract.C_FOLLOWING: following ? 1 : 0, + ConversationTableContract.C_SAW_LAST_MESSAGE: sawLastMessage ? 1 : 0, + ConversationTableContract.C_MEMBERS: members.join(","), + }; + } } diff --git a/lib/utils/list_utils.dart b/lib/utils/list_utils.dart new file mode 100644 index 0000000..a1eb577 --- /dev/null +++ b/lib/utils/list_utils.dart @@ -0,0 +1,14 @@ +/// List utilities +/// +/// @author Pierre HUBERT + +/// Transform a list of string into something else +List stringListToIntList(List srcList){ + List list = List(); + + srcList.forEach((e){ + list.add(int.parse(e)); + }); + + return list; +} \ No newline at end of file