1
0
mirror of https://gitlab.com/comunic/comunicmobile synced 2025-06-19 00:05:16 +00:00

Start conversation upgrade

This commit is contained in:
2021-03-10 17:54:41 +01:00
parent b094361f5a
commit dacccf57b5
35 changed files with 818 additions and 520 deletions

View File

@ -0,0 +1,121 @@
import 'dart:convert';
import 'dart:io';
import 'package:comunic/constants.dart';
import 'package:path/path.dart' as path;
import 'package:path_provider/path_provider.dart';
/// Base serialization helper
///
/// @author Pierre Hubert
abstract class SerializableElement<T> extends Comparable<T> {
Map<String, dynamic> toJson();
}
abstract class BaseSerializationHelper<T extends SerializableElement> {
/// List cache
List<T> _cache;
/// The name of the type of data to serialise
String get type;
/// Parse an json entry into a [T] object
T parse(Map<String, dynamic> m);
/// Get the file where data should be stored
Future<File> _getFilePath() async {
final dir = await getApplicationDocumentsDirectory();
final targetDir =
Directory(path.join(dir.absolute.path, SERIALIZATION_DIRECTORY));
targetDir.create(recursive: true);
return File(path.join(targetDir.absolute.path, type));
}
/// Load the cache
Future<void> _loadCache() async {
if (_cache != null) return;
try {
final file = await _getFilePath();
if (!await file.exists()) return _cache = List();
final List<dynamic> json = jsonDecode(await file.readAsString());
_cache = json.cast<Map<String, dynamic>>().map(parse).toList();
_cache.sort();
} catch (e, s) {
print("Failed to read serialized data! $e => $s");
_cache = List();
}
}
/// Save the cache to the persistent memory
Future<void> _saveCache() async {
final file = await _getFilePath();
await file.writeAsString(jsonEncode(
_cache.map((e) => e.toJson()).toList().cast<Map<String, dynamic>>()));
}
/// Get the current list of elements
Future<List<T>> getList() async {
await _loadCache();
return List.from(_cache);
}
/// Set a new list of conversations
Future<void> setList(List<T> list) async {
_cache = List.from(list);
await _saveCache();
}
/// Insert new element
Future<void> insert(T el) async {
await _loadCache();
_cache.add(el);
_cache.sort();
await _saveCache();
}
/// Insert new element
Future<void> insertMany(List<T> els) async {
await _loadCache();
_cache.addAll(els);
_cache.sort();
await _saveCache();
}
/// Check if any entry in the last match the predicate
Future<bool> any(bool isContained(T t)) async {
await _loadCache();
return _cache.any((element) => isContained(element));
}
/// Check if any entry in the last match the predicate
Future<T> first(bool filter(T t)) async {
await _loadCache();
return _cache.firstWhere((element) => filter(element));
}
/// Replace an element with another one
Future<void> insertOrReplaceElement(bool isToReplace(T t), T newEl) async {
await _loadCache();
// Insert or replace the element
_cache.where((element) => !isToReplace(element)).toList();
_cache.add(newEl);
_cache.sort();
await _saveCache();
}
/// Remove elements
Future<void> removeElement(bool isToRemove(T t)) async {
await _loadCache();
_cache.removeWhere((element) => isToRemove(element));
await _saveCache();
}
}

View File

@ -0,0 +1,50 @@
import 'dart:collection';
import 'package:comunic/helpers/serialization/base_serialization_helper.dart';
import 'package:comunic/lists/conversation_messages_list.dart';
import 'package:comunic/models/conversation_message.dart';
/// Conversations serialization helper
///
/// @author Pierre Hubert
final HashMap<int, ConversationsMessagesSerializationHelper> _instances =
HashSet() as HashMap<int, ConversationsMessagesSerializationHelper>;
class ConversationsMessagesSerializationHelper
extends BaseSerializationHelper<ConversationMessage> {
final int convID;
ConversationsMessagesSerializationHelper._(int convID)
: convID = convID,
assert(convID != null);
factory ConversationsMessagesSerializationHelper(int convID) {
if (!_instances.containsKey(convID))
_instances[convID] = ConversationsMessagesSerializationHelper._(convID);
return _instances[convID];
}
@override
ConversationMessage parse(Map<String, dynamic> m) =>
ConversationMessage.fromJson(m);
@override
String get type => "conv-messages-$convID";
Future<ConversationMessagesList> getList() async =>
ConversationMessagesList()..addAll(await super.getList());
Future<void> insertOrReplace(ConversationMessage msg) async =>
await insertOrReplaceElement((t) => t.id == msg.id, msg);
Future<void> remove(ConversationMessage msg) async =>
await removeElement((t) => t.id == msg.id);
/// Insert or replace a list of messages
Future<void> insertOrReplaceAll(List<ConversationMessage> list) async {
for (var message in list)
await insertOrReplaceElement((t) => t.id == message.id, message);
}
}

View File

@ -0,0 +1,32 @@
import 'package:comunic/helpers/serialization/base_serialization_helper.dart';
import 'package:comunic/lists/conversations_list.dart';
import 'package:comunic/models/conversation.dart';
/// Conversations serialization helper
///
/// @author Pierre Hubert
var _cache;
class ConversationsSerializationHelper
extends BaseSerializationHelper<Conversation> {
/// Singleton
factory ConversationsSerializationHelper() {
if (_cache == null) _cache = ConversationsSerializationHelper._();
return _cache;
}
ConversationsSerializationHelper._();
@override
Conversation parse(Map<String, dynamic> m) => Conversation.fromJson(m);
@override
String get type => "conversations";
Future<ConversationsList> getList() async =>
ConversationsList()..addAll(await super.getList());
/// Get a conversation
Future<Conversation> get(int id) => first((t) => t.id == id);
}