forked from cwtch.im/cwtch-ui
port most gomobile FlwtchWorker calls to lcg to MainActivity; sendmessage sets lastSeen time
This commit is contained in:
parent
e7c5b2cfa5
commit
1cffea5c1a
|
@ -86,6 +86,7 @@ class FlwtchWorker(context: Context, parameters: WorkerParameters) :
|
|||
try {
|
||||
val evt = MainActivity.AppbusEvent(Cwtch.getAppBusEvent())
|
||||
// TODO replace this notification block with the NixNotification manager in dart as it has access to contact names and also needs less working around
|
||||
|
||||
if (evt.EventType == "NewMessageFromPeer" || evt.EventType == "NewMessageFromGroup") {
|
||||
val data = JSONObject(evt.Data)
|
||||
val handle = data.getString("RemotePeer");
|
||||
|
@ -222,212 +223,26 @@ class FlwtchWorker(context: Context, parameters: WorkerParameters) :
|
|||
intent.putExtra("EventID", evt.EventID)
|
||||
LocalBroadcastManager.getInstance(applicationContext).sendBroadcast(intent)
|
||||
}
|
||||
if (evt.EventType == "Shutdown") {
|
||||
Log.i(TAG, "processing shutdown event, exiting FlwtchWorker/Start()...");
|
||||
return Result.success()
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, "Error in handleCwtch: " + e.toString() + " :: " + e.getStackTrace());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
"ReconnectCwtchForeground" -> {
|
||||
Cwtch.reconnectCwtchForeground()
|
||||
}
|
||||
"CreateProfile" -> {
|
||||
val nick = (a.get("nick") as? String) ?: ""
|
||||
val pass = (a.get("pass") as? String) ?: ""
|
||||
Cwtch.createProfile(nick, pass)
|
||||
}
|
||||
"LoadProfiles" -> {
|
||||
val pass = (a.get("pass") as? String) ?: ""
|
||||
Cwtch.loadProfiles(pass)
|
||||
}
|
||||
"ChangePassword" -> {
|
||||
val profile = (a.get("ProfileOnion") as? String) ?: ""
|
||||
val pass = (a.get("OldPass") as? String) ?: ""
|
||||
val passNew = (a.get("NewPass") as? String) ?: ""
|
||||
val passNew2 = (a.get("NewPassAgain") as? String) ?: ""
|
||||
Cwtch.changePassword(profile, pass, passNew, passNew2)
|
||||
}
|
||||
"GetMessage" -> {
|
||||
val profile = (a.get("ProfileOnion") as? String) ?: ""
|
||||
val conversation = a.getInt("conversation").toLong()
|
||||
val indexI = a.getInt("index").toLong()
|
||||
Log.d(TAG, "Cwtch GetMessage " + profile + " " + conversation.toString() + " " + indexI.toString())
|
||||
return Result.success(Data.Builder().putString("result", Cwtch.getMessage(profile, conversation, indexI)).build())
|
||||
}
|
||||
"GetMessageByID" -> {
|
||||
val profile = (a.get("ProfileOnion") as? String) ?: ""
|
||||
val conversation = a.getInt("conversation").toLong()
|
||||
val id = a.getInt("id").toLong()
|
||||
return Result.success(Data.Builder().putString("result", Cwtch.getMessageByID(profile, conversation, id)).build())
|
||||
}
|
||||
"GetMessageByContentHash" -> {
|
||||
val profile = (a.get("ProfileOnion") as? String) ?: ""
|
||||
val conversation = a.getInt("conversation").toLong()
|
||||
val contentHash = (a.get("contentHash") as? String) ?: ""
|
||||
return Result.success(Data.Builder().putString("result", Cwtch.getMessagesByContentHash(profile, conversation, contentHash)).build())
|
||||
}
|
||||
"UpdateMessageAttribute" -> {
|
||||
val profile = (a.get("ProfileOnion") as? String) ?: ""
|
||||
val conversation = a.getInt("conversation").toLong()
|
||||
val channel = a.getInt("chanenl").toLong()
|
||||
val midx = a.getInt("midx").toLong()
|
||||
val key = (a.get("key") as? String) ?: ""
|
||||
val value = (a.get("value") as? String) ?: ""
|
||||
Cwtch.setMessageAttribute(profile, conversation, channel, midx, key, value)
|
||||
}
|
||||
"AcceptConversation" -> {
|
||||
val profile = (a.get("ProfileOnion") as? String) ?: ""
|
||||
val conversation = a.getInt("conversation").toLong()
|
||||
Cwtch.acceptConversation(profile, conversation)
|
||||
}
|
||||
"BlockContact" -> {
|
||||
val profile = (a.get("ProfileOnion") as? String) ?: ""
|
||||
val conversation = a.getInt("conversation").toLong()
|
||||
Cwtch.blockContact(profile, conversation)
|
||||
}
|
||||
"UnblockContact" -> {
|
||||
val profile = (a.get("ProfileOnion") as? String) ?: ""
|
||||
val conversation = a.getInt("conversation").toLong()
|
||||
Cwtch.unblockContact(profile, conversation)
|
||||
}
|
||||
|
||||
"DownloadFile" -> {
|
||||
val profile = (a.get("ProfileOnion") as? String) ?: ""
|
||||
val conversation = a.getInt("conversation").toLong()
|
||||
val filepath = (a.get("filepath") as? String) ?: ""
|
||||
val manifestpath = (a.get("manifestpath") as? String) ?: ""
|
||||
val filekey = (a.get("filekey") as? String) ?: ""
|
||||
// FIXME: Prevent spurious calls by Intent
|
||||
if (profile != "") {
|
||||
Cwtch.downloadFile(profile, conversation, filepath, manifestpath, filekey)
|
||||
}
|
||||
}
|
||||
"CheckDownloadStatus" -> {
|
||||
val profile = (a.get("ProfileOnion") as? String) ?: ""
|
||||
val fileKey = (a.get("fileKey") as? String) ?: ""
|
||||
Cwtch.checkDownloadStatus(profile, fileKey)
|
||||
}
|
||||
"VerifyOrResumeDownload" -> {
|
||||
val profile = (a.get("ProfileOnion") as? String) ?: ""
|
||||
val conversation = a.getInt("conversation").toLong()
|
||||
val fileKey = (a.get("fileKey") as? String) ?: ""
|
||||
Cwtch.verifyOrResumeDownload(profile, conversation, fileKey)
|
||||
}
|
||||
"SendProfileEvent" -> {
|
||||
val onion = (a.get("onion") as? String) ?: ""
|
||||
val jsonEvent = (a.get("jsonEvent") as? String) ?: ""
|
||||
Cwtch.sendProfileEvent(onion, jsonEvent)
|
||||
}
|
||||
"SendAppEvent" -> {
|
||||
val jsonEvent = (a.get("jsonEvent") as? String) ?: ""
|
||||
Cwtch.sendAppEvent(jsonEvent)
|
||||
}
|
||||
"ResetTor" -> {
|
||||
Cwtch.resetTor()
|
||||
}
|
||||
"ImportBundle" -> {
|
||||
val profile = (a.get("ProfileOnion") as? String) ?: ""
|
||||
val bundle = (a.get("bundle") as? String) ?: ""
|
||||
Cwtch.importBundle(profile, bundle)
|
||||
}
|
||||
"CreateGroup" -> {
|
||||
val profile = (a.get("ProfileOnion") as? String) ?: ""
|
||||
val server = (a.get("server") as? String) ?: ""
|
||||
val groupName = (a.get("groupName") as? String) ?: ""
|
||||
Cwtch.createGroup(profile, server, groupName)
|
||||
}
|
||||
"DeleteProfile" -> {
|
||||
val profile = (a.get("ProfileOnion") as? String) ?: ""
|
||||
val pass = (a.get("pass") as? String) ?: ""
|
||||
Cwtch.deleteProfile(profile, pass)
|
||||
}
|
||||
"ArchiveConversation" -> {
|
||||
val profile = (a.get("ProfileOnion") as? String) ?: ""
|
||||
val conversation = a.getInt("conversation").toLong()
|
||||
Cwtch.archiveConversation(profile, conversation)
|
||||
}
|
||||
"DeleteConversation" -> {
|
||||
val profile = (a.get("ProfileOnion") as? String) ?: ""
|
||||
val conversation = a.getInt("conversation").toLong()
|
||||
Cwtch.deleteContact(profile, conversation)
|
||||
}
|
||||
"SetProfileAttribute" -> {
|
||||
val profile = (a.get("ProfileOnion") as? String) ?: ""
|
||||
val key = (a.get("Key") as? String) ?: ""
|
||||
val v = (a.get("Val") as? String) ?: ""
|
||||
Cwtch.setProfileAttribute(profile, key, v)
|
||||
}
|
||||
"SetConversationAttribute" -> {
|
||||
val profile = (a.get("ProfileOnion") as? String) ?: ""
|
||||
val conversation = a.getInt("conversation").toLong()
|
||||
val key = (a.get("Key") as? String) ?: ""
|
||||
val v = (a.get("Val") as? String) ?: ""
|
||||
Cwtch.setConversationAttribute(profile, conversation, key, v)
|
||||
}
|
||||
"Shutdown" -> {
|
||||
Cwtch.shutdownCwtch();
|
||||
return Result.success()
|
||||
}
|
||||
"LoadServers" -> {
|
||||
val password = (a.get("Password") as? String) ?: ""
|
||||
Cwtch.loadServers(password)
|
||||
}
|
||||
"CreateServer" -> {
|
||||
val password = (a.get("Password") as? String) ?: ""
|
||||
val desc = (a.get("Description") as? String) ?: ""
|
||||
val autostart = (a.get("Autostart") as? Boolean) ?: false
|
||||
Cwtch.createServer(password, desc, autostart)
|
||||
}
|
||||
"DeleteServer" -> {
|
||||
val serverOnion = (a.get("ServerOnion") as? String) ?: ""
|
||||
val password = (a.get("Password") as? String) ?: ""
|
||||
Cwtch.deleteServer(serverOnion, password)
|
||||
}
|
||||
"LaunchServers" -> {
|
||||
Cwtch.launchServers()
|
||||
}
|
||||
"LaunchServer" -> {
|
||||
val serverOnion = (a.get("ServerOnion") as? String) ?: ""
|
||||
Cwtch.launchServer(serverOnion)
|
||||
}
|
||||
"StopServer" -> {
|
||||
val serverOnion = (a.get("ServerOnion") as? String) ?: ""
|
||||
Cwtch.stopServer(serverOnion)
|
||||
}
|
||||
"StopServers" -> {
|
||||
Cwtch.stopServers()
|
||||
}
|
||||
"DestroyServers" -> {
|
||||
Cwtch.destroyServers()
|
||||
}
|
||||
"SetServerAttribute" -> {
|
||||
val serverOnion = (a.get("ServerOnion") as? String) ?: ""
|
||||
val key = (a.get("Key") as? String) ?: ""
|
||||
val v = (a.get("Val") as? String) ?: ""
|
||||
Cwtch.setServerAttribute(serverOnion, key, v)
|
||||
}
|
||||
// Event passing translations from Flutter to Kotlin worker scope so the worker can use them
|
||||
"L10nInit" -> {
|
||||
notificationSimple = (a.get("notificationSimple") as? String) ?: "New Message"
|
||||
notificationConversationInfo = (a.get("notificationConversationInfo") as? String)
|
||||
?: "New Message From "
|
||||
}
|
||||
"ExportProfile" -> {
|
||||
val profileOnion = (a.get("ProfileOnion") as? String) ?: ""
|
||||
val file = StringBuilder().append(this.applicationContext.cacheDir).append("/").append((a.get("file") as? String) ?: "").toString()
|
||||
Log.i("FlwtchWorker", "constructing exported file " + file);
|
||||
Cwtch.exportProfile(profileOnion,file)
|
||||
}
|
||||
"ImportProfile" -> {
|
||||
val file = (a.get("file") as? String) ?: ""
|
||||
val pass = (a.get("pass") as? String) ?: ""
|
||||
return Result.success(Data.Builder().putString("result", Cwtch.importProfile(file, pass)).build());
|
||||
}
|
||||
else -> {
|
||||
Log.i(TAG, "unknown command: " + method);
|
||||
return Result.failure()
|
||||
}
|
||||
}
|
||||
|
||||
return Result.success()
|
||||
}
|
||||
|
||||
|
|
|
@ -55,6 +55,7 @@ class MainActivity: FlutterActivity() {
|
|||
private val CHANNEL_NOTIF_CLICK = "im.cwtch.flwtch/notificationClickHandler"
|
||||
private val CHANNEL_SHUTDOWN_CLICK = "im.cwtch.flwtch/shutdownClickHandler"
|
||||
|
||||
private val TAG: String = "MainActivity.kt"
|
||||
// WorkManager tag applied to all Start() infinite coroutines
|
||||
val WORKER_TAG = "cwtchEventBusWorker"
|
||||
|
||||
|
@ -267,6 +268,194 @@ class MainActivity: FlutterActivity() {
|
|||
val filepath: String = call.argument("filepath") ?: ""
|
||||
result.success(Cwtch.shareFile(profile, conversation.toLong(), filepath))
|
||||
}
|
||||
|
||||
"CreateProfile" -> {
|
||||
val nick: String = call.argument("nick") ?: ""
|
||||
val pass: String = call.argument("pass") ?: ""
|
||||
Cwtch.createProfile(nick, pass)
|
||||
}
|
||||
"LoadProfiles" -> {
|
||||
val pass: String = call.argument("pass") ?: ""
|
||||
Cwtch.loadProfiles(pass)
|
||||
}
|
||||
"ChangePassword" -> {
|
||||
val profile: String = call.argument("ProfileOnion") ?: ""
|
||||
val pass: String = call.argument("OldPass") ?: ""
|
||||
val passNew: String = call.argument("NewPass") ?: ""
|
||||
val passNew2: String = call.argument("NewPassAgain") ?: ""
|
||||
Cwtch.changePassword(profile, pass, passNew, passNew2)
|
||||
}
|
||||
"GetMessage" -> {
|
||||
val profile: String = call.argument("ProfileOnion") ?: ""
|
||||
val conversation: Int = call.argument("conversation") ?: 0
|
||||
val indexI: Int = call.argument("index") ?: 0
|
||||
result.success(Data.Builder().putString("result", Cwtch.getMessage(profile, conversation.toLong(), indexI.toLong())).build())
|
||||
}
|
||||
"GetMessageByID" -> {
|
||||
val profile: String = call.argument("ProfileOnion") ?: ""
|
||||
val conversation: Int = call.argument("conversation") ?: 0
|
||||
val id: Int = call.argument("id") ?: 0
|
||||
result.success(Data.Builder().putString("result", Cwtch.getMessageByID(profile, conversation.toLong(), id.toLong())).build())
|
||||
}
|
||||
"GetMessageByContentHash" -> {
|
||||
val profile: String = call.argument("ProfileOnion") ?: ""
|
||||
val conversation: Int = call.argument("conversation") ?: 0
|
||||
val contentHash: String = call.argument("contentHash") ?: ""
|
||||
result.success(Data.Builder().putString("result", Cwtch.getMessagesByContentHash(profile, conversation.toLong(), contentHash)).build())
|
||||
}
|
||||
"SetMessageAttribute" -> {
|
||||
val profile: String = call.argument("ProfileOnion") ?: ""
|
||||
val conversation: Int = call.argument("conversation") ?: 0
|
||||
val channel: Int = call.argument("Chanenl") ?: 0
|
||||
val midx: Int = call.argument("Message") ?: 0
|
||||
val key: String = call.argument("key") ?: ""
|
||||
val value: String = call.argument("value") ?: ""
|
||||
Cwtch.setMessageAttribute(profile, conversation.toLong(), channel.toLong(), midx.toLong(), key, value)
|
||||
}
|
||||
"AcceptConversation" -> {
|
||||
val profile: String = call.argument("ProfileOnion") ?: ""
|
||||
val conversation: Int = call.argument("conversation") ?: 0
|
||||
Cwtch.acceptConversation(profile, conversation.toLong())
|
||||
}
|
||||
"BlockContact" -> {
|
||||
val profile: String = call.argument("ProfileOnion") ?: ""
|
||||
val conversation: Int = call.argument("conversation") ?: 0
|
||||
Cwtch.blockContact(profile, conversation.toLong())
|
||||
}
|
||||
"UnblockContact" -> {
|
||||
val profile: String = call.argument("ProfileOnion") ?: ""
|
||||
val conversation: Int = call.argument("conversation") ?: 0
|
||||
Cwtch.unblockContact(profile, conversation.toLong())
|
||||
}
|
||||
|
||||
"DownloadFile" -> {
|
||||
val profile: String = call.argument("ProfileOnion") ?: ""
|
||||
val conversation: Int = call.argument("conversation") ?: 0
|
||||
val filepath: String = call.argument("filepath") ?: ""
|
||||
val manifestpath: String = call.argument("manifestpath") ?: ""
|
||||
val filekey: String = call.argument("filekey") ?: ""
|
||||
// FIXME: Prevent spurious calls by Intent
|
||||
if (profile != "") {
|
||||
Cwtch.downloadFile(profile, conversation.toLong(), filepath, manifestpath, filekey)
|
||||
}
|
||||
}
|
||||
"CheckDownloadStatus" -> {
|
||||
val profile: String = call.argument("ProfileOnion") ?: ""
|
||||
val fileKey: String = call.argument("fileKey") ?: ""
|
||||
Cwtch.checkDownloadStatus(profile, fileKey)
|
||||
}
|
||||
"VerifyOrResumeDownload" -> {
|
||||
val profile: String = call.argument("ProfileOnion") ?: ""
|
||||
val conversation: Int = call.argument("conversation") ?: 0
|
||||
val fileKey: String = call.argument("fileKey") ?: ""
|
||||
Cwtch.verifyOrResumeDownload(profile, conversation.toLong(), fileKey)
|
||||
}
|
||||
"SendProfileEvent" -> {
|
||||
val onion: String= call.argument("onion") ?: ""
|
||||
val jsonEvent: String = call.argument("jsonEvent") ?: ""
|
||||
Cwtch.sendProfileEvent(onion, jsonEvent)
|
||||
}
|
||||
"SendAppEvent" -> {
|
||||
val jsonEvent: String = call.argument("jsonEvent") ?: ""
|
||||
Cwtch.sendAppEvent(jsonEvent)
|
||||
}
|
||||
"ResetTor" -> {
|
||||
Cwtch.resetTor()
|
||||
}
|
||||
"ImportBundle" -> {
|
||||
val profile: String = call.argument("ProfileOnion") ?: ""
|
||||
val bundle: String = call.argument("bundle") ?: ""
|
||||
Cwtch.importBundle(profile, bundle)
|
||||
}
|
||||
"CreateGroup" -> {
|
||||
val profile: String = call.argument("ProfileOnion") ?: ""
|
||||
val server: String = call.argument("server") ?: ""
|
||||
val groupName: String = call.argument("groupName") ?: ""
|
||||
Cwtch.createGroup(profile, server, groupName)
|
||||
}
|
||||
"DeleteProfile" -> {
|
||||
val profile: String = call.argument("ProfileOnion") ?: ""
|
||||
val pass: String = call.argument("pass") ?: ""
|
||||
Cwtch.deleteProfile(profile, pass)
|
||||
}
|
||||
"ArchiveConversation" -> {
|
||||
val profile: String = call.argument("ProfileOnion") ?: ""
|
||||
val conversation: Int = call.argument("conversation") ?: 0
|
||||
Cwtch.archiveConversation(profile, conversation.toLong())
|
||||
}
|
||||
"DeleteConversation" -> {
|
||||
val profile: String = call.argument("ProfileOnion") ?: ""
|
||||
val conversation: Int = call.argument("conversation") ?: 0
|
||||
Cwtch.deleteContact(profile, conversation.toLong())
|
||||
}
|
||||
"SetProfileAttribute" -> {
|
||||
val profile: String = call.argument("ProfileOnion") ?: ""
|
||||
val key: String = call.argument("Key") ?: ""
|
||||
val v: String = call.argument("Val") ?: ""
|
||||
Cwtch.setProfileAttribute(profile, key, v)
|
||||
}
|
||||
"SetConversationAttribute" -> {
|
||||
val profile: String = call.argument("ProfileOnion") ?: ""
|
||||
val conversation: Int = call.argument("conversation") ?: 0
|
||||
val key: String = call.argument("Key") ?: ""
|
||||
val v: String = call.argument("Val") ?: ""
|
||||
Cwtch.setConversationAttribute(profile, conversation.toLong(), key, v)
|
||||
}
|
||||
"LoadServers" -> {
|
||||
val password: String = call.argument("Password") ?: ""
|
||||
Cwtch.loadServers(password)
|
||||
}
|
||||
"CreateServer" -> {
|
||||
val password: String = call.argument("Password") ?: ""
|
||||
val desc: String = call.argument("Description") ?: ""
|
||||
val autostart: Boolean = call.argument("Autostart") ?: false
|
||||
Cwtch.createServer(password, desc, autostart)
|
||||
}
|
||||
"DeleteServer" -> {
|
||||
val serverOnion: String = call.argument("ServerOnion") ?: ""
|
||||
val password: String = call.argument("Password") ?: ""
|
||||
Cwtch.deleteServer(serverOnion, password)
|
||||
}
|
||||
"LaunchServers" -> {
|
||||
Cwtch.launchServers()
|
||||
}
|
||||
"LaunchServer" -> {
|
||||
val serverOnion: String = call.argument("ServerOnion") ?: ""
|
||||
Cwtch.launchServer(serverOnion)
|
||||
}
|
||||
"StopServer" -> {
|
||||
val serverOnion: String = call.argument("ServerOnion") ?: ""
|
||||
Cwtch.stopServer(serverOnion)
|
||||
}
|
||||
"StopServers" -> {
|
||||
Cwtch.stopServers()
|
||||
}
|
||||
"DestroyServers" -> {
|
||||
Cwtch.destroyServers()
|
||||
}
|
||||
"SetServerAttribute" -> {
|
||||
val serverOnion: String = call.argument("ServerOnion") ?: ""
|
||||
val key: String = call.argument("Key") ?: ""
|
||||
val v: String = call.argument("Val") ?: ""
|
||||
Cwtch.setServerAttribute(serverOnion, key, v)
|
||||
}
|
||||
"ExportProfile" -> {
|
||||
val profileOnion: String = call.argument("ProfileOnion") ?: ""
|
||||
val file: String = StringBuilder().append(this.applicationContext.cacheDir).append("/").append(call.argument("file") ?: "").toString()
|
||||
Log.i("FlwtchWorker", "constructing exported file " + file);
|
||||
Cwtch.exportProfile(profileOnion,file)
|
||||
}
|
||||
"ImportProfile" -> {
|
||||
val file: String = call.argument("file") ?: ""
|
||||
val pass: String = call.argument("pass") ?: ""
|
||||
Data.Builder().putString("result", Cwtch.importProfile(file, pass)).build()
|
||||
}
|
||||
"ReconnectCwtchForeground" -> {
|
||||
Cwtch.reconnectCwtchForeground()
|
||||
}
|
||||
"Shutdown" -> {
|
||||
Cwtch.shutdownCwtch();
|
||||
}
|
||||
else -> {
|
||||
// ...otherwise fallthru to a normal ffi method call (and return the result using the result callback)
|
||||
val data: Data = Data.Builder().putString(FlwtchWorker.KEY_METHOD, method).putString(FlwtchWorker.KEY_ARGS, JSONObject(argmap).toString()).build()
|
||||
|
|
|
@ -175,7 +175,7 @@ class ProfileInfoState extends ChangeNotifier {
|
|||
this._unreadMessages += contact["numUnread"] as int;
|
||||
if (profileContact != null) {
|
||||
profileContact.status = contact["status"];
|
||||
profileContact.totalMessages = contact["numMessages"]; // Todo: trigger cache update (bulk upload)
|
||||
profileContact.totalMessages = contact["numMessages"];
|
||||
profileContact.unreadMessages = contact["numUnread"];
|
||||
profileContact.lastMessageTime = DateTime.fromMillisecondsSinceEpoch(1000 * int.parse(contact["lastMsgTime"]));
|
||||
} else {
|
||||
|
@ -198,7 +198,6 @@ class ProfileInfoState extends ChangeNotifier {
|
|||
notificationPolicy: contact["notificationPolicy"] ?? "ConversationNotificationPolicy.Default",
|
||||
));
|
||||
}
|
||||
unreadMessages += int.parse(contact["numUnread"]);
|
||||
});
|
||||
}
|
||||
this._contacts.resort();
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import 'dart:convert';
|
||||
import 'dart:io';
|
||||
import 'package:crypto/crypto.dart';
|
||||
import 'package:cwtch/cwtch/cwtch.dart';
|
||||
import 'package:cwtch/cwtch_icons_icons.dart';
|
||||
import 'package:cwtch/models/appstate.dart';
|
||||
import 'package:cwtch/models/chatmessage.dart';
|
||||
|
@ -278,6 +279,8 @@ class _MessageViewState extends State<MessageView> {
|
|||
|
||||
ctrlrCompose.clear();
|
||||
focusNode.requestFocus();
|
||||
|
||||
Provider.of<FlwtchState>(context, listen: false).cwtch.SetConversationAttribute(profileOnion, identifier, LastMessageSeenTimeKey, DateTime.now().toIso8601String());
|
||||
}
|
||||
|
||||
Widget _buildComposeBox() {
|
||||
|
|
Loading…
Reference in New Issue