1
0
mirror of https://gitlab.com/comunic/comunicmobile synced 2024-11-22 04:49:21 +00:00

Store locally the list of conversations

This commit is contained in:
Pierre HUBERT 2019-04-24 14:25:46 +02:00
parent 7f41f0dae1
commit eb34ed5c3d
7 changed files with 121 additions and 18 deletions

View File

@ -1,3 +1,4 @@
import 'package:comunic/helpers/database/conversations_database_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';
@ -9,6 +10,9 @@ import 'package:comunic/utils/account_utils.dart';
/// @author Pierre HUBERT /// @author Pierre HUBERT
class ConversationsHelper { class ConversationsHelper {
final ConversationsDatabaseHelper _conversationsDatabaseHelper =
ConversationsDatabaseHelper();
/// Download the list of conversations from the server /// Download the list of conversations from the server
Future<ConversationsList> downloadList() async { Future<ConversationsList> downloadList() async {
final response = final response =
@ -28,6 +32,10 @@ class ConversationsHelper {
members: f["members"].map<int>((f) => int.parse(f)).toList(), members: f["members"].map<int>((f) => int.parse(f)).toList(),
))); )));
// Update the database
await _conversationsDatabaseHelper.clearTable();
await _conversationsDatabaseHelper.insertAll(list);
return list; return list;
} on Exception catch (e) { } on Exception catch (e) {
print(e.toString()); print(e.toString());
@ -46,14 +54,11 @@ class ConversationsHelper {
for (int i = 0; i < 3 && i < conversation.members.length; i++) for (int i = 0; i < 3 && i < conversation.members.length; i++)
if (conversation.members[i] != userID()) { if (conversation.members[i] != userID()) {
name += (count > 0 ? ", " : "") + name += (count > 0 ? ", " : "") +
users users.getUser(conversation.members[i]).fullName;
.getUser(conversation.members[i])
.fullName;
count++; count++;
} }
if(conversation.members.length > 3) if (conversation.members.length > 3) name += ", ...";
name += ", ...";
return name; return name;
} }

View File

@ -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<Conversation> {
@override
Conversation initializeFromMap(Map<String, dynamic> map) {
return Conversation.fromMap(map);
}
@override
String tableName() {
return ConversationTableContract.TABLE_NAME;
}
}

View File

@ -22,4 +22,16 @@ abstract class UserTableContract {
static const C_VISIBILITY = "visibility"; static const C_VISIBILITY = "visibility";
static const C_VIRTUAL_DIRECTORY = "virtual_directory"; static const C_VIRTUAL_DIRECTORY = "virtual_directory";
static const C_ACCOUNT_IMAGE_URL = "account_image_url"; 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";
} }

View File

@ -34,7 +34,14 @@ abstract class DatabaseHelper {
/// Currently : delete all the database tables and initialize it again /// Currently : delete all the database tables and initialize it again
static Future<void> _performDatabaseUpdate( static Future<void> _performDatabaseUpdate(
Database db, int oldVersion, int newVersion) async { 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); await _initializeDatabase(db, newVersion);
} }
@ -45,9 +52,20 @@ abstract class DatabaseHelper {
"${UserTableContract.C_ID} INTEGER PRIMARY KEY, " "${UserTableContract.C_ID} INTEGER PRIMARY KEY, "
"${UserTableContract.C_FIRST_NAME} TEXT, " "${UserTableContract.C_FIRST_NAME} TEXT, "
"${UserTableContract.C_LAST_NAME} TEXT, " "${UserTableContract.C_LAST_NAME} TEXT, "
"${UserTableContract.C_VISIBILITY} TEXT," "${UserTableContract.C_VISIBILITY} TEXT, "
"${UserTableContract.C_VIRTUAL_DIRECTORY} TEXT," "${UserTableContract.C_VIRTUAL_DIRECTORY} TEXT, "
"${UserTableContract.C_ACCOUNT_IMAGE_URL} 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"
")");
} }
} }

View File

@ -9,7 +9,6 @@ import 'package:comunic/models/cache_model.dart';
/// @author Pierre HUBERT /// @author Pierre HUBERT
abstract class ModelDatabaseHelper<T extends CacheModel> { abstract class ModelDatabaseHelper<T extends CacheModel> {
/// Get the name of the target table. Must be specified by the children /// Get the name of the target table. Must be specified by the children
/// of this class /// of this class
String tableName(); String tableName();
@ -19,8 +18,7 @@ abstract class ModelDatabaseHelper<T extends CacheModel> {
/// Insert an entry in the database /// Insert an entry in the database
Future<void> _insertDB(T el) async { Future<void> _insertDB(T el) async {
await (await DatabaseHelper.get()) await (await DatabaseHelper.get()).insert(tableName(), el.toMap());
.insert(tableName(), el.toMap());
} }
/// Update an element in the database /// Update an element in the database
@ -48,6 +46,11 @@ abstract class ModelDatabaseHelper<T extends CacheModel> {
return null; return null;
} }
/// Empty the table
Future<void> clearTable() async {
await (await DatabaseHelper.get()).execute("DELETE FROM ${tableName()}");
}
/// Check out whether an element specified with its [id] is present /// Check out whether an element specified with its [id] is present
/// or not in the local database /// or not in the local database
Future<bool> has(int id) async { Future<bool> has(int id) async {
@ -65,8 +68,13 @@ abstract class ModelDatabaseHelper<T extends CacheModel> {
/// Insert or update an important amount of elements /// Insert or update an important amount of elements
Future<void> insertOrUpdateAll(List<T> list) async { Future<void> insertOrUpdateAll(List<T> list) async {
for(int i = 0; i < list.length; i++) for (int i = 0; i < list.length; i++) await insertOrUpdate(list[i]);
await insertOrUpdate(list[i]);
} }
} /// Insert an important amount of elements
///
/// This might throw if there are conflicting IDs
Future<void> insertAll(List<T> list) async {
for (T el in list) await _insertDB(el);
}
}

View File

@ -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'; import 'package:meta/meta.dart';
/// Conversation model /// Conversation model
/// ///
/// @author Pierre HUBERT /// @author Pierre HUBERT
class Conversation { class Conversation extends CacheModel {
final int id;
final int ownerID; final int ownerID;
final int lastActive; final int lastActive;
final String name; final String name;
@ -14,7 +16,7 @@ class Conversation {
final List<int> members; final List<int> members;
const Conversation({ const Conversation({
@required this.id, @required int id,
@required this.ownerID, @required this.ownerID,
@required this.lastActive, @required this.lastActive,
@required this.name, @required this.name,
@ -26,8 +28,32 @@ class Conversation {
assert(lastActive != null), assert(lastActive != null),
assert(following != null), assert(following != null),
assert(sawLastMessage != null), assert(sawLastMessage != null),
assert(members != null); assert(members != null),
super(id: id);
/// Check out whether a conversation has a fixed name or not /// Check out whether a conversation has a fixed name or not
bool get has_name => this.name != null; bool get has_name => this.name != null;
Conversation.fromMap(Map<String, dynamic> 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<String, dynamic> 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(","),
};
}
} }

14
lib/utils/list_utils.dart Normal file
View File

@ -0,0 +1,14 @@
/// List utilities
///
/// @author Pierre HUBERT
/// Transform a list of string into something else
List<int> stringListToIntList(List<String> srcList){
List<int> list = List();
srcList.forEach((e){
list.add(int.parse(e));
});
return list;
}