store last seen time in lcg and handle unread counts
continuous-integration/drone/pr Build is passing Details

This commit is contained in:
Dan Ballard 2022-04-01 15:54:06 -07:00
parent 6eaf95a33b
commit e08114881c
8 changed files with 27 additions and 2 deletions

View File

@ -1 +1 @@
2022-03-23-19-06-v1.6.0-13-g1acae32
2022-04-04-17-46-v1.6.0-15-g97defdf

View File

@ -1 +1 @@
2022-03-23-23-06-v1.6.0-13-g1acae32
2022-04-04-21-46-v1.6.0-15-g97defdf

View File

@ -2,6 +2,8 @@
// Details: https://docs.openprivacy.ca/cwtch-security-handbook/profile_encryption_and_storage.html
const DefaultPassword = "be gay do crime";
const LastMessageSeenTimeKey = "profile.lastMessageSeenTime";
abstract class Cwtch {
// ignore: non_constant_identifier_names
Future<void> Start();

View File

@ -18,6 +18,8 @@ import '../config.dart';
import '../errorHandler.dart';
import '../settings.dart';
typedef SeenMessageCallback = Function(String, int, DateTime);
// Class that handles libcwtch-go events (received either via ffi with an isolate or gomobile over a method channel from kotlin)
// Takes Notifiers and triggers them on appropriate events
class CwtchNotifier {
@ -32,6 +34,8 @@ class CwtchNotifier {
String? notificationSimple;
String? notificationConversationInfo;
SeenMessageCallback? seenMessageCallback;
CwtchNotifier(
ProfileListState pcn, Settings settingsCN, ErrorHandler errorCN, TorStatus torStatusCN, NotificationsManager notificationManagerP, AppState appStateCN, ServerListState serverListStateCN) {
profileCN = pcn;
@ -48,6 +52,10 @@ class CwtchNotifier {
this.notificationConversationInfo = notificationConversationInfo;
}
void setMessageSeenCallback(SeenMessageCallback callback) {
seenMessageCallback = callback;
}
void handleMessage(String type, dynamic data) {
//EnvironmentConfig.debugLog("NewEvent $type $data");
switch (type) {
@ -164,6 +172,10 @@ class CwtchNotifier {
var selectedConversation = selectedProfile && appState.selectedConversation == identifier;
var notification = data["notification"];
if (selectedConversation && seenMessageCallback != null) {
seenMessageCallback!(data["ProfileOnion"]!, identifier, DateTime.now().toUtc());
}
if (notification == "SimpleEvent") {
notificationManager.notify(notificationSimple ?? "New Message", "", 0);
} else if (notification == "ContactInfo") {
@ -229,6 +241,9 @@ class CwtchNotifier {
// and ensure that malicious contacts in groups can only set this timestamp to a value within the range of `last seen message time`
// and `local now`.
profileCN.getProfile(data["ProfileOnion"])?.newMessage(identifier, idx, timestampSent, senderHandle, senderImage, isAuto, data["Data"], contenthash, selectedProfile, selectedConversation);
if (selectedConversation && seenMessageCallback != null) {
seenMessageCallback!(data["ProfileOnion"]!, identifier, DateTime.now().toUtc());
}
if (notification == "SimpleEvent") {
notificationManager.notify(notificationSimple ?? "New Message", "", 0);

View File

@ -133,6 +133,7 @@ class CwtchFfi implements Cwtch {
}
library = DynamicLibrary.open(libraryPath);
cwtchNotifier = _cwtchNotifier;
cwtchNotifier.setMessageSeenCallback((String profile, int conversation, DateTime time) => {this.SetConversationAttribute(profile, conversation, LastMessageSeenTimeKey, time.toIso8601String())});
}
// ignore: non_constant_identifier_names

View File

@ -35,6 +35,7 @@ class CwtchGomobile implements Cwtch {
CwtchGomobile(CwtchNotifier _cwtchNotifier) {
print("gomobile.dart: CwtchGomobile()");
cwtchNotifier = _cwtchNotifier;
cwtchNotifier.setMessageSeenCallback((String profile, int conversation, DateTime time) => {this.SetConversationAttribute(profile, conversation, LastMessageSeenTimeKey, time.toIso8601String())});
androidHomeDirectory = getApplicationDocumentsDirectory();
androidLibraryDir = appInfoPlatform.invokeMethod('getNativeLibDir');

View File

@ -50,6 +50,7 @@ class ProfileInfoState extends ChangeNotifier {
List<dynamic> contacts = jsonDecode(contactsJson);
this._contacts.addAll(contacts.map((contact) {
this._unreadMessages += contact["numUnread"] as int;
return ContactInfoState(this.onion, contact["identifier"], contact["onion"],
nickname: contact["name"],
status: contact["status"],
@ -164,12 +165,14 @@ class ProfileInfoState extends ChangeNotifier {
this._nickname = name;
this._imagePath = picture;
this._online = online;
this._unreadMessages = 0;
this.replaceServers(serverJson);
if (contactsJson != null && contactsJson != "" && contactsJson != "null") {
List<dynamic> contacts = jsonDecode(contactsJson);
contacts.forEach((contact) {
var profileContact = this._contacts.getContact(contact["identifier"]);
this._unreadMessages += contact["numUnread"] as int;
if (profileContact != null) {
profileContact.status = contact["status"];
profileContact.totalMessages = contact["numMessages"]; // Todo: trigger cache update (bulk upload)

View File

@ -1,3 +1,4 @@
import 'package:cwtch/cwtch/cwtch.dart';
import 'package:cwtch/cwtch_icons_icons.dart';
import 'package:cwtch/models/appstate.dart';
import 'package:cwtch/models/contact.dart';
@ -38,6 +39,8 @@ void selectConversation(BuildContext context, int handle) {
// if in singlepane mode, push to the stack
var isLandscape = Provider.of<AppState>(context, listen: false).isLandscape(context);
if (Provider.of<Settings>(context, listen: false).uiColumns(isLandscape).length == 1) _pushMessageView(context, handle);
// Set last message seen time in backend
Provider.of<FlwtchState>(context, listen: false).cwtch.SetConversationAttribute(Provider.of<ProfileInfoState>(context, listen: false).onion, handle, LastMessageSeenTimeKey, DateTime.now().toUtc().toIso8601String());
}
void _pushMessageView(BuildContext context, int handle) {