Porting Android over to new API
continuous-integration/drone/pr Build is pending Details

This commit is contained in:
Sarah Jamie Lewis 2021-12-03 11:28:10 -08:00
parent d6839c62e3
commit c42be6224d
15 changed files with 132 additions and 169 deletions

View File

@ -181,61 +181,69 @@ class FlwtchWorker(context: Context, parameters: WorkerParameters) :
Cwtch.loadProfiles(pass) Cwtch.loadProfiles(pass)
} }
"GetMessage" -> { "GetMessage" -> {
val profile = (a.get("profile") as? String) ?: "" val profile = (a.get("ProfileOnion") as? String) ?: ""
val handle = (a.get("contact") as? String) ?: "" val conversation = a.getInt("conversation").toLong()
val indexI = a.getInt("index") val indexI = a.getInt("index").toLong()
return Result.success(Data.Builder().putString("result", Cwtch.getMessage(profile, handle, indexI.toLong())).build()) 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" -> { "GetMessageByContentHash" -> {
val profile = (a.get("profile") as? String) ?: ""
val handle = (a.get("contact") as? String) ?: ""
val contentHash = (a.get("contentHash") as? String) ?: ""
return Result.success(Data.Builder().putString("result", Cwtch.getMessagesByContentHash(profile, handle, contentHash)).build())
}
"UpdateMessageFlags" -> {
val profile = (a.get("profile") as? String) ?: ""
val handle = (a.get("contact") as? String) ?: ""
val midx = (a.get("midx") as? Long) ?: 0
val flags = (a.get("flags") as? Long) ?: 0
Cwtch.updateMessageFlags(profile, handle, midx, flags)
}
"AcceptContact" -> {
val profile = (a.get("ProfileOnion") as? String) ?: "" val profile = (a.get("ProfileOnion") as? String) ?: ""
val handle = (a.get("handle") as? String) ?: "" val conversation = a.getInt("conversation").toLong()
Cwtch.acceptContact(profile, handle) 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" -> { "BlockContact" -> {
val profile = (a.get("ProfileOnion") as? String) ?: "" val profile = (a.get("ProfileOnion") as? String) ?: ""
val handle = (a.get("handle") as? String) ?: "" val conversation = a.getInt("conversation").toLong()
Cwtch.blockContact(profile, handle) Cwtch.blockContact(profile, conversation)
} }
"SendMessage" -> { "SendMessage" -> {
val profile = (a.get("ProfileOnion") as? String) ?: "" val profile = (a.get("ProfileOnion") as? String) ?: ""
val handle = (a.get("handle") as? String) ?: "" val conversation = a.getInt("conversation").toLong()
val message = (a.get("message") as? String) ?: "" val message = (a.get("message") as? String) ?: ""
Cwtch.sendMessage(profile, handle, message) Cwtch.sendMessage(profile, conversation, message)
} }
"SendInvitation" -> { "SendInvitation" -> {
val profile = (a.get("ProfileOnion") as? String) ?: "" val profile = (a.get("ProfileOnion") as? String) ?: ""
val handle = (a.get("handle") as? String) ?: "" val conversation = a.getInt("conversation").toLong()
val target = (a.get("target") as? String) ?: "" val target = (a.get("target") as? Long) ?: -1
Cwtch.sendInvitation(profile, handle, target) Cwtch.sendInvitation(profile, conversation, target)
} }
"ShareFile" -> { "ShareFile" -> {
val profile = (a.get("ProfileOnion") as? String) ?: "" val profile = (a.get("ProfileOnion") as? String) ?: ""
val handle = (a.get("handle") as? String) ?: "" val conversation = a.getInt("conversation").toLong()
val filepath = (a.get("filepath") as? String) ?: "" val filepath = (a.get("filepath") as? String) ?: ""
Cwtch.shareFile(profile, handle, filepath) Cwtch.shareFile(profile, conversation, filepath)
} }
"DownloadFile" -> { "DownloadFile" -> {
val profile = (a.get("ProfileOnion") as? String) ?: "" val profile = (a.get("ProfileOnion") as? String) ?: ""
val handle = (a.get("handle") as? String) ?: "" val conversation = a.getInt("conversation").toLong()
val filepath = (a.get("filepath") as? String) ?: "" val filepath = (a.get("filepath") as? String) ?: ""
val manifestpath = (a.get("manifestpath") as? String) ?: "" val manifestpath = (a.get("manifestpath") as? String) ?: ""
val filekey = (a.get("filekey") as? String) ?: "" val filekey = (a.get("filekey") as? String) ?: ""
// FIXME: Prevent spurious calls by Intent // FIXME: Prevent spurious calls by Intent
if (profile != "") { if (profile != "") {
Cwtch.downloadFile(profile, handle, filepath, manifestpath, filekey) Cwtch.downloadFile(profile, conversation, filepath, manifestpath, filekey)
} }
} }
"CheckDownloadStatus" -> { "CheckDownloadStatus" -> {
@ -245,9 +253,9 @@ class FlwtchWorker(context: Context, parameters: WorkerParameters) :
} }
"VerifyOrResumeDownload" -> { "VerifyOrResumeDownload" -> {
val profile = (a.get("ProfileOnion") as? String) ?: "" val profile = (a.get("ProfileOnion") as? String) ?: ""
val handle = (a.get("handle") as? String) ?: "" val conversation = a.getInt("conversation").toLong()
val fileKey = (a.get("fileKey") as? String) ?: "" val fileKey = (a.get("fileKey") as? String) ?: ""
Cwtch.verifyOrResumeDownload(profile, handle, fileKey) Cwtch.verifyOrResumeDownload(profile, conversation, fileKey)
} }
"SendProfileEvent" -> { "SendProfileEvent" -> {
val onion = (a.get("onion") as? String) ?: "" val onion = (a.get("onion") as? String) ?: ""
@ -266,13 +274,6 @@ class FlwtchWorker(context: Context, parameters: WorkerParameters) :
val bundle = (a.get("bundle") as? String) ?: "" val bundle = (a.get("bundle") as? String) ?: ""
Cwtch.importBundle(profile, bundle) Cwtch.importBundle(profile, bundle)
} }
"SetGroupAttribute" -> {
val profile = (a.get("ProfileOnion") as? String) ?: ""
val groupHandle = (a.get("groupHandle") as? String) ?: ""
val key = (a.get("key") as? String) ?: ""
val value = (a.get("value") as? String) ?: ""
Cwtch.setGroupAttribute(profile, groupHandle, key, value)
}
"CreateGroup" -> { "CreateGroup" -> {
val profile = (a.get("ProfileOnion") as? String) ?: "" val profile = (a.get("ProfileOnion") as? String) ?: ""
val server = (a.get("server") as? String) ?: "" val server = (a.get("server") as? String) ?: ""
@ -286,18 +287,13 @@ class FlwtchWorker(context: Context, parameters: WorkerParameters) :
} }
"ArchiveConversation" -> { "ArchiveConversation" -> {
val profile = (a.get("ProfileOnion") as? String) ?: "" val profile = (a.get("ProfileOnion") as? String) ?: ""
val contactHandle = (a.get("handle") as? String) ?: "" val conversation = (a.get("conversation") as? Long) ?: -1
Cwtch.archiveConversation(profile, contactHandle) Cwtch.archiveConversation(profile, conversation)
} }
"DeleteContact" -> { "DeleteConversation" -> {
val profile = (a.get("ProfileOnion") as? String) ?: "" val profile = (a.get("ProfileOnion") as? String) ?: ""
val handle = (a.get("handle") as? String) ?: "" val conversation = (a.get("conversation") as? Long) ?: -1
Cwtch.deleteContact(profile, handle) Cwtch.deleteContact(profile, conversation)
}
"RejectInvite" -> {
val profile = (a.get("ProfileOnion") as? String) ?: ""
val groupHandle = (a.get("groupHandle") as? String) ?: ""
Cwtch.rejectInvite(profile, groupHandle)
} }
"SetProfileAttribute" -> { "SetProfileAttribute" -> {
val profile = (a.get("ProfileOnion") as? String) ?: "" val profile = (a.get("ProfileOnion") as? String) ?: ""
@ -305,12 +301,12 @@ class FlwtchWorker(context: Context, parameters: WorkerParameters) :
val v = (a.get("Val") as? String) ?: "" val v = (a.get("Val") as? String) ?: ""
Cwtch.setProfileAttribute(profile, key, v) Cwtch.setProfileAttribute(profile, key, v)
} }
"SetContactAttribute" -> { "SetConversationAttribute" -> {
val profile = (a.get("ProfileOnion") as? String) ?: "" val profile = (a.get("ProfileOnion") as? String) ?: ""
val contact = (a.get("Contact") as? String) ?: "" val conversation = (a.get("conversation") as? Long) ?: -1
val key = (a.get("Key") as? String) ?: "" val key = (a.get("Key") as? String) ?: ""
val v = (a.get("Val") as? String) ?: "" val v = (a.get("Val") as? String) ?: ""
Cwtch.setContactAttribute(profile, contact, key, v) Cwtch.setConversationAttribute(profile, conversation, key, v)
} }
"Shutdown" -> { "Shutdown" -> {
Cwtch.shutdownCwtch(); Cwtch.shutdownCwtch();
@ -354,7 +350,10 @@ class FlwtchWorker(context: Context, parameters: WorkerParameters) :
val v = (a.get("Val") as? String) ?: "" val v = (a.get("Val") as? String) ?: ""
Cwtch.setServerAttribute(serverOnion, key, v) Cwtch.setServerAttribute(serverOnion, key, v)
} }
else -> return Result.failure() else -> {
Log.i("FlwtchWorker", "unknown command: " + method);
return Result.failure()
}
} }
return Result.success() return Result.success()
} }

View File

@ -152,6 +152,7 @@ class MainActivity: FlutterActivity() {
Log.i("handleCwtch:WorkManager", "canceling ${workInfo.id} bc tags don't include $uniqueTag") Log.i("handleCwtch:WorkManager", "canceling ${workInfo.id} bc tags don't include $uniqueTag")
WorkManager.getInstance(this).cancelWorkById(workInfo.id) WorkManager.getInstance(this).cancelWorkById(workInfo.id)
} }
WorkManager.getInstance(this).cancelWorkById(workInfo.id)
} }
WorkManager.getInstance(this).pruneWork() WorkManager.getInstance(this).pruneWork()

View File

@ -10,8 +10,6 @@ abstract class Cwtch {
// ignore: non_constant_identifier_names // ignore: non_constant_identifier_names
Future<void> ReconnectCwtchForeground(); Future<void> ReconnectCwtchForeground();
// ignore: non_constant_identifier_names
void SelectProfile(String onion);
// ignore: non_constant_identifier_names // ignore: non_constant_identifier_names
void CreateProfile(String nick, String pass); void CreateProfile(String nick, String pass);
// ignore: non_constant_identifier_names // ignore: non_constant_identifier_names
@ -69,8 +67,6 @@ abstract class Cwtch {
// ignore: non_constant_identifier_names // ignore: non_constant_identifier_names
void ImportBundle(String profile, String bundle); void ImportBundle(String profile, String bundle);
// ignore: non_constant_identifier_names // ignore: non_constant_identifier_names
void RejectInvite(String profileOnion, int groupHandle);
// ignore: non_constant_identifier_names
void SetProfileAttribute(String profile, String key, String val); void SetProfileAttribute(String profile, String key, String val);
// ignore: non_constant_identifier_names // ignore: non_constant_identifier_names
void SetConversationAttribute(String profile, int conversation, String key, String val); void SetConversationAttribute(String profile, int conversation, String key, String val);

View File

@ -139,8 +139,8 @@ class CwtchNotifier {
} else { } else {
profileCN.getProfile(data["ProfileOnion"])?.contactList.getContact(identifier)!.newMarker++; profileCN.getProfile(data["ProfileOnion"])?.contactList.getContact(identifier)!.newMarker++;
} }
profileCN.getProfile(data["ProfileOnion"])?.contactList.getContact(identifier)!.totalMessages++;
profileCN.getProfile(data["ProfileOnion"])?.contactList.updateLastMessageTime(identifier, DateTime.now()); profileCN.getProfile(data["ProfileOnion"])?.contactList.updateLastMessageTime(identifier, DateTime.now());
profileCN.getProfile(data["ProfileOnion"])?.contactList.getContact(identifier)!.totalMessages++;
// We only ever see messages from authenticated peers. // We only ever see messages from authenticated peers.
// If the contact is marked as offline then override this - can happen when the contact is removed from the front // If the contact is marked as offline then override this - can happen when the contact is removed from the front
@ -155,13 +155,12 @@ class CwtchNotifier {
// We don't use these anymore, IndexedAcknowledgement is more suited to the UI front end... // We don't use these anymore, IndexedAcknowledgement is more suited to the UI front end...
break; break;
case "IndexedAcknowledgement": case "IndexedAcknowledgement":
var messageID = data["Index"]; var conversation = int.parse(data["ConversationID"]);
var identifier = int.parse(data["ConversationID"]); var message_index = int.parse(data["Index"]);
var idx = identifier.toString() + messageID; var contact = profileCN.getProfile(data["ProfileOnion"])?.contactList.getContact(conversation);
// We return -1 for protocol message acks if there is no message // We return -1 for protocol message acks if there is no message
if (idx == "-1") break; if (message_index == -1) break;
var key = profileCN.getProfile(data["ProfileOnion"])?.contactList.getContact(identifier)!.getMessageKey(idx); var key = contact!.getMessageKeyOrFail(conversation, message_index, contact.lastMessageTime);
if (key == null) break; if (key == null) break;
try { try {
var message = Provider.of<MessageMetadata>(key.currentContext!, listen: false); var message = Provider.of<MessageMetadata>(key.currentContext!, listen: false);
@ -169,8 +168,8 @@ class CwtchNotifier {
// We only ever see acks from authenticated peers. // We only ever see acks from authenticated peers.
// If the contact is marked as offline then override this - can happen when the contact is removed from the front // If the contact is marked as offline then override this - can happen when the contact is removed from the front
// end during syncing. // end during syncing.
if (profileCN.getProfile(data["ProfileOnion"])?.contactList.getContact(identifier)!.isOnline() == false) { if (profileCN.getProfile(data["ProfileOnion"])?.contactList.getContact(conversation)!.isOnline() == false) {
profileCN.getProfile(data["ProfileOnion"])?.contactList.getContact(identifier)!.status = "Authenticated"; profileCN.getProfile(data["ProfileOnion"])?.contactList.getContact(conversation)!.status = "Authenticated";
} }
message.ackd = true; message.ackd = true;
} catch (e) { } catch (e) {
@ -225,27 +224,12 @@ class CwtchNotifier {
// Ignore // Ignore
break; break;
case "IndexedFailure": case "IndexedFailure":
var idx = data["Index"]; var contact = profileCN.getProfile(data["ProfileOnion"])?.contactList.findContact(data["RemotePeer"]);
var key = profileCN.getProfile(data["ProfileOnion"])?.contactList.findContact(data["RemotePeer"])?.getMessageKey(idx); var idx = int.parse(data["Index"]);
try { var key = contact?.getMessageKeyOrFail(contact.identifier, idx, contact.lastMessageTime);
var message = Provider.of<MessageMetadata>(key!.currentContext!, listen: false); if (key != null) {
message.error = true;
} catch (e) {
// ignore, we likely have an old key that has been replaced with an actual signature
}
break;
case "SendMessageToGroupError":
// from me (already displayed - do not update counter)
EnvironmentConfig.debugLog("SendMessageToGroupError: $data");
var idx = data["Signature"];
var key = profileCN.getProfile(data["ProfileOnion"])?.contactList.findContact(data["GroupID"])!.getMessageKey(idx);
if (key == null) break;
try {
var message = Provider.of<MessageMetadata>(key.currentContext!, listen: false); var message = Provider.of<MessageMetadata>(key.currentContext!, listen: false);
if (message == null) break;
message.error = true; message.error = true;
} catch (e) {
// ignore, we likely have an old key that has been replaced with an actual signature
} }
break; break;
case "AppError": case "AppError":

View File

@ -261,16 +261,6 @@ class CwtchFfi implements Cwtch {
} }
} }
// ignore: non_constant_identifier_names
void SelectProfile(String onion) async {
var selectProfileC = library.lookup<NativeFunction<get_json_blob_string_function>>("c_SelectProfile");
// ignore: non_constant_identifier_names
final SelectProfile = selectProfileC.asFunction<GetJsonBlobStringFn>();
final ut8Onion = onion.toNativeUtf8();
SelectProfile(ut8Onion, ut8Onion.length);
malloc.free(ut8Onion);
}
// ignore: non_constant_identifier_names // ignore: non_constant_identifier_names
void CreateProfile(String nick, String pass) { void CreateProfile(String nick, String pass) {
var createProfileC = library.lookup<NativeFunction<void_from_string_string_function>>("c_CreateProfile"); var createProfileC = library.lookup<NativeFunction<void_from_string_string_function>>("c_CreateProfile");
@ -460,17 +450,6 @@ class CwtchFfi implements Cwtch {
malloc.free(u2); malloc.free(u2);
} }
@override
// ignore: non_constant_identifier_names
void RejectInvite(String profileOnion, int groupHandle) {
var rejectInvite = library.lookup<NativeFunction<string_int_to_void_function>>("c_RejectInvite");
// ignore: non_constant_identifier_names
final RejectInvite = rejectInvite.asFunction<VoidFromStringIntFn>();
final u1 = profileOnion.toNativeUtf8();
RejectInvite(u1, u1.length, groupHandle);
malloc.free(u1);
}
@override @override
// ignore: non_constant_identifier_names // ignore: non_constant_identifier_names
void CreateGroup(String profileOnion, String server, String groupName) { void CreateGroup(String profileOnion, String server, String groupName) {

View File

@ -66,11 +66,6 @@ class CwtchGomobile implements Cwtch {
cwtchNotifier.handleMessage(call.method, obj); cwtchNotifier.handleMessage(call.method, obj);
} }
// ignore: non_constant_identifier_names
void SelectProfile(String onion) {
cwtchPlatform.invokeMethod("SelectProfile", {"profile": onion});
}
// ignore: non_constant_identifier_names // ignore: non_constant_identifier_names
void CreateProfile(String nick, String pass) { void CreateProfile(String nick, String pass) {
cwtchPlatform.invokeMethod("CreateProfile", {"nick": nick, "pass": pass}); cwtchPlatform.invokeMethod("CreateProfile", {"nick": nick, "pass": pass});
@ -87,13 +82,13 @@ class CwtchGomobile implements Cwtch {
} }
// ignore: non_constant_identifier_names // ignore: non_constant_identifier_names
Future<dynamic> GetMessage(String profile, int handle, int index) { Future<dynamic> GetMessage(String profile, int conversation, int index) {
return cwtchPlatform.invokeMethod("GetMessage", {"profile": profile, "contact": handle, "index": index}); return cwtchPlatform.invokeMethod("GetMessage", {"ProfileOnion": profile, "conversation": conversation, "index": index});
} }
// ignore: non_constant_identifier_names // ignore: non_constant_identifier_names
Future<dynamic> GetMessageByID(String profile, int handle, int index) { Future<dynamic> GetMessageByID(String profile, int conversation, int id) {
return cwtchPlatform.invokeMethod("GetMessageByID", {"profile": profile, "contact": handle, "index": index}); return cwtchPlatform.invokeMethod("GetMessageByID", {"ProfileOnion": profile, "conversation": conversation, "id": id});
} }
@override @override
@ -113,43 +108,43 @@ class CwtchGomobile implements Cwtch {
@override @override
// ignore: non_constant_identifier_names // ignore: non_constant_identifier_names
void AcceptContact(String profileOnion, int contactHandle) { void AcceptContact(String profileOnion, int conversation) {
cwtchPlatform.invokeMethod("AcceptContact", {"ProfileOnion": profileOnion, "handle": contactHandle}); cwtchPlatform.invokeMethod("AcceptContact", {"ProfileOnion": profileOnion, "conversation": conversation});
} }
@override @override
// ignore: non_constant_identifier_names // ignore: non_constant_identifier_names
void BlockContact(String profileOnion, int contactHandle) { void BlockContact(String profileOnion, int conversation) {
cwtchPlatform.invokeMethod("BlockContact", {"ProfileOnion": profileOnion, "handle": contactHandle}); cwtchPlatform.invokeMethod("BlockContact", {"ProfileOnion": profileOnion, "conversation": conversation});
} }
@override @override
// ignore: non_constant_identifier_names // ignore: non_constant_identifier_names
void SendMessage(String profileOnion, int contactHandle, String message) { void SendMessage(String profileOnion, int conversation, String message) {
cwtchPlatform.invokeMethod("SendMessage", {"ProfileOnion": profileOnion, "handle": contactHandle, "message": message}); cwtchPlatform.invokeMethod("SendMessage", {"ProfileOnion": profileOnion, "conversation": conversation, "message": message});
} }
@override @override
// ignore: non_constant_identifier_names // ignore: non_constant_identifier_names
void SendInvitation(String profileOnion, int contactHandle, int target) { void SendInvitation(String profileOnion, int conversation, int target) {
cwtchPlatform.invokeMethod("SendInvitation", {"ProfileOnion": profileOnion, "handle": contactHandle, "target": target}); cwtchPlatform.invokeMethod("SendInvitation", {"ProfileOnion": profileOnion, "conversation": conversation, "target": target});
} }
@override @override
// ignore: non_constant_identifier_names // ignore: non_constant_identifier_names
void ShareFile(String profileOnion, int contactHandle, String filepath) { void ShareFile(String profileOnion, int conversation, String filepath) {
cwtchPlatform.invokeMethod("ShareFile", {"ProfileOnion": profileOnion, "handle": contactHandle, "filepath": filepath}); cwtchPlatform.invokeMethod("ShareFile", {"ProfileOnion": profileOnion, "conversation": conversation, "filepath": filepath});
} }
@override @override
// ignore: non_constant_identifier_names // ignore: non_constant_identifier_names
void DownloadFile(String profileOnion, int contactHandle, String filepath, String manifestpath, String filekey) { void DownloadFile(String profileOnion, int conversation, String filepath, String manifestpath, String filekey) {
cwtchPlatform.invokeMethod("DownloadFile", {"ProfileOnion": profileOnion, "handle": contactHandle, "filepath": filepath, "manifestpath": manifestpath, "filekey": filekey}); cwtchPlatform.invokeMethod("DownloadFile", {"ProfileOnion": profileOnion, "conversation": conversation, "filepath": filepath, "manifestpath": manifestpath, "filekey": filekey});
} }
// ignore: non_constant_identifier_names // ignore: non_constant_identifier_names
void CreateDownloadableFile(String profileOnion, int contactHandle, String filenameSuggestion, String filekey) { void CreateDownloadableFile(String profileOnion, int conversation, String filenameSuggestion, String filekey) {
cwtchPlatform.invokeMethod("CreateDownloadableFile", {"ProfileOnion": profileOnion, "handle": contactHandle, "filename": filenameSuggestion, "filekey": filekey}); cwtchPlatform.invokeMethod("CreateDownloadableFile", {"ProfileOnion": profileOnion, "conversation": conversation, "filename": filenameSuggestion, "filekey": filekey});
} }
@override @override
@ -160,8 +155,8 @@ class CwtchGomobile implements Cwtch {
@override @override
// ignore: non_constant_identifier_names // ignore: non_constant_identifier_names
void VerifyOrResumeDownload(String profileOnion, int contactHandle, String filekey) { void VerifyOrResumeDownload(String profileOnion, int conversation, String filekey) {
cwtchPlatform.invokeMethod("VerifyOrResumeDownload", {"ProfileOnion": profileOnion, "handle": contactHandle, "filekey": filekey}); cwtchPlatform.invokeMethod("VerifyOrResumeDownload", {"ProfileOnion": profileOnion, "conversation": conversation, "filekey": filekey});
} }
@override @override
@ -176,18 +171,6 @@ class CwtchGomobile implements Cwtch {
cwtchPlatform.invokeMethod("ImportBundle", {"ProfileOnion": profileOnion, "bundle": bundle}); cwtchPlatform.invokeMethod("ImportBundle", {"ProfileOnion": profileOnion, "bundle": bundle});
} }
@override
// ignore: non_constant_identifier_names
void SetGroupAttribute(String profileOnion, String groupHandle, String key, String value) {
cwtchPlatform.invokeMethod("SetGroupAttribute", {"ProfileOnion": profileOnion, "groupHandle": groupHandle, "key": key, "value": value});
}
@override
// ignore: non_constant_identifier_names
void RejectInvite(String profileOnion, int groupHandle) {
cwtchPlatform.invokeMethod("RejectInvite", {"ProfileOnion": profileOnion, "groupHandle": groupHandle});
}
@override @override
void CreateGroup(String profileOnion, String server, String groupName) { void CreateGroup(String profileOnion, String server, String groupName) {
cwtchPlatform.invokeMethod("CreateGroup", {"ProfileOnion": profileOnion, "server": server, "groupName": groupName}); cwtchPlatform.invokeMethod("CreateGroup", {"ProfileOnion": profileOnion, "server": server, "groupName": groupName});
@ -195,14 +178,14 @@ class CwtchGomobile implements Cwtch {
@override @override
// ignore: non_constant_identifier_names // ignore: non_constant_identifier_names
void DeleteContact(String profileOnion, int handle) { void DeleteContact(String profileOnion, int conversation) {
cwtchPlatform.invokeMethod("DeleteContact", {"ProfileOnion": profileOnion, "handle": handle}); cwtchPlatform.invokeMethod("DeleteContact", {"ProfileOnion": profileOnion, "conversation": conversation});
} }
@override @override
// ignore: non_constant_identifier_names // ignore: non_constant_identifier_names
void ArchiveConversation(String profileOnion, int contactHandle) { void ArchiveConversation(String profileOnion, int conversation) {
cwtchPlatform.invokeMethod("ArchiveConversation", {"ProfileOnion": profileOnion, "handle": contactHandle}); cwtchPlatform.invokeMethod("ArchiveConversation", {"ProfileOnion": profileOnion, "conversation": conversation});
} }
@override @override
@ -213,8 +196,8 @@ class CwtchGomobile implements Cwtch {
@override @override
// ignore: non_constant_identifier_names // ignore: non_constant_identifier_names
void SetConversationAttribute(String profile, int contact, String key, String val) { void SetConversationAttribute(String profile, int conversation, String key, String val) {
cwtchPlatform.invokeMethod("SetContactAttribute", {"ProfileOnion": profile, "Contact": contact, "Key": key, "Val": val}); cwtchPlatform.invokeMethod("SetContactAttribute", {"ProfileOnion": profile, "conversation": conversation, "Key": key, "Val": val});
} }
@override @override
@ -278,12 +261,12 @@ class CwtchGomobile implements Cwtch {
} }
@override @override
Future GetMessageByContentHash(String profile, int handle, String contentHash) { Future GetMessageByContentHash(String profile, int conversation, String contentHash) {
return cwtchPlatform.invokeMethod("GetMessageByContentHash", {"profile": profile, "contact": handle, "contentHash": contentHash}); return cwtchPlatform.invokeMethod("GetMessageByContentHash", {"ProfileOnion": profile, "conversation": conversation, "contentHash": contentHash});
} }
@override @override
void SetMessageAttribute(String profile, int conversation, int channel, int message, String key, String val) { void SetMessageAttribute(String profile, int conversation, int channel, int message, String key, String val) {
cwtchPlatform.invokeMethod("SetMessageAttribute", {"ProfileOnion": profile, "Conversation": conversation, "Channel": channel, "Message": message, "Key": key, "Val": val}); cwtchPlatform.invokeMethod("SetMessageAttribute", {"ProfileOnion": profile, "conversation": conversation, "Channel": channel, "Message": message, "Key": key, "Val": val});
} }
} }

View File

@ -1,5 +1,6 @@
import 'dart:convert'; import 'dart:convert';
import 'package:cwtch/config.dart';
import 'package:cwtch/widgets/messagerow.dart'; import 'package:cwtch/widgets/messagerow.dart';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:cwtch/models/profileservers.dart'; import 'package:cwtch/models/profileservers.dart';
@ -657,11 +658,23 @@ class ContactInfoState extends ChangeNotifier {
} }
} }
GlobalKey<MessageRowState> getMessageKey(String index) { GlobalKey<MessageRowState> getMessageKey(int conversation, int message, DateTime lastread) {
String index = "c: " + conversation.toString() + " m:" + message.toString(); //+ " lr:" +lastMessageTime.toIso8601String();
//EnvironmentConfig.debugLog("looked up key $index");
if (keys[index] == null) { if (keys[index] == null) {
keys[index] = GlobalKey<MessageRowState>(); keys[index] = GlobalKey<MessageRowState>();
} }
GlobalKey<MessageRowState> ret = keys[index]!; GlobalKey<MessageRowState> ret = keys[index]!;
return ret; return ret;
} }
GlobalKey<MessageRowState>? getMessageKeyOrFail(int conversation, int message, DateTime lastread) {
String index = "c: " + conversation.toString() + " m:" + message.toString(); // + " lr:" +lastMessageTime.toIso8601String();
if (keys[index] == null) {
return null;
}
GlobalKey<MessageRowState> ret = keys[index]!;
return ret;
}
} }

View File

@ -21,7 +21,6 @@ class FileMessage extends Message {
return ChangeNotifierProvider.value( return ChangeNotifierProvider.value(
value: this.metadata, value: this.metadata,
builder: (bcontext, child) { builder: (bcontext, child) {
String idx = this.metadata.conversationIdentifier.toString() + this.metadata.messageID.toString();
dynamic shareObj = jsonDecode(this.content); dynamic shareObj = jsonDecode(this.content);
if (shareObj == null) { if (shareObj == null) {
return MessageRow(MalformedBubble()); return MessageRow(MalformedBubble());
@ -35,7 +34,9 @@ class FileMessage extends Message {
return MessageRow(MalformedBubble()); return MessageRow(MalformedBubble());
} }
return MessageRow(FileBubble(nameSuggestion, rootHash, nonce, fileSize), key: Provider.of<ContactInfoState>(bcontext).getMessageKey(idx)); var lrt = Provider.of<ContactInfoState>(bcontext).lastMessageTime;
return MessageRow(FileBubble(nameSuggestion, rootHash, nonce, fileSize),
key: Provider.of<ContactInfoState>(bcontext).getMessageKey(this.metadata.conversationIdentifier, this.metadata.messageID, lrt));
}); });
} }

View File

@ -21,7 +21,6 @@ class InviteMessage extends Message {
return ChangeNotifierProvider.value( return ChangeNotifierProvider.value(
value: this.metadata, value: this.metadata,
builder: (bcontext, child) { builder: (bcontext, child) {
String idx = this.metadata.conversationIdentifier.toString() + this.metadata.messageID.toString();
String inviteTarget; String inviteTarget;
String inviteNick; String inviteNick;
String invite = this.content; String invite = this.content;
@ -40,7 +39,9 @@ class InviteMessage extends Message {
return MessageRow(MalformedBubble()); return MessageRow(MalformedBubble());
} }
} }
return MessageRow(InvitationBubble(overlay, inviteTarget, inviteNick, invite), key: Provider.of<ContactInfoState>(bcontext).getMessageKey(idx)); var lrt = Provider.of<ContactInfoState>(bcontext).lastMessageTime;
return MessageRow(InvitationBubble(overlay, inviteTarget, inviteNick, invite),
key: Provider.of<ContactInfoState>(bcontext).getMessageKey(this.metadata.conversationIdentifier, this.metadata.messageID, lrt));
}); });
} }

View File

@ -94,7 +94,7 @@ class QuotedMessage extends Message {
return ChangeNotifierProvider.value( return ChangeNotifierProvider.value(
value: this.metadata, value: this.metadata,
builder: (bcontext, child) { builder: (bcontext, child) {
String idx = this.metadata.conversationIdentifier.toString() + this.metadata.messageID.toString(); var lrt = Provider.of<ContactInfoState>(bcontext).lastMessageTime;
return MessageRow( return MessageRow(
QuotedMessageBubble(message["body"], quotedMessage.then((LocallyIndexedMessage? localIndex) { QuotedMessageBubble(message["body"], quotedMessage.then((LocallyIndexedMessage? localIndex) {
if (localIndex != null) { if (localIndex != null) {
@ -102,7 +102,7 @@ class QuotedMessage extends Message {
} }
return MalformedMessage(this.metadata); return MalformedMessage(this.metadata);
})), })),
key: Provider.of<ContactInfoState>(bcontext).getMessageKey(idx)); key: Provider.of<ContactInfoState>(bcontext).getMessageKey(this.metadata.conversationIdentifier, this.metadata.messageID, lrt));
}); });
} catch (e) { } catch (e) {
return MalformedMessage(this.metadata).getWidget(context); return MalformedMessage(this.metadata).getWidget(context);

View File

@ -1,5 +1,8 @@
import 'package:cwtch/models/message.dart'; import 'package:cwtch/models/message.dart';
import 'package:cwtch/models/messages/malformedmessage.dart';
import 'package:cwtch/widgets/malformedbubble.dart';
import 'package:cwtch/widgets/messagebubble.dart'; import 'package:cwtch/widgets/messagebubble.dart';
import 'package:cwtch/widgets/messageloadingbubble.dart';
import 'package:cwtch/widgets/messagerow.dart'; import 'package:cwtch/widgets/messagerow.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart'; import 'package:flutter/widgets.dart';
@ -32,8 +35,10 @@ class TextMessage extends Message {
return ChangeNotifierProvider.value( return ChangeNotifierProvider.value(
value: this.metadata, value: this.metadata,
builder: (bcontext, child) { builder: (bcontext, child) {
String idx = this.metadata.conversationIdentifier.toString() + this.metadata.messageID.toString(); var lrt = Provider.of<ContactInfoState>(bcontext).lastMessageTime;
return MessageRow(MessageBubble(this.content), key: Provider.of<ContactInfoState>(bcontext).getMessageKey(idx)); var key = Provider.of<ContactInfoState>(bcontext).getMessageKey(this.metadata.conversationIdentifier, this.metadata.messageID, lrt);
return MessageRow(MessageBubble(this.content), key: key);
}); });
} }
} }

View File

@ -121,7 +121,7 @@ class _ContactRowState extends State<ContactRow> {
void _btnReject() { void _btnReject() {
ContactInfoState contact = Provider.of<ContactInfoState>(context, listen: false); ContactInfoState contact = Provider.of<ContactInfoState>(context, listen: false);
if (contact.isGroup == true) { if (contact.isGroup == true) {
Provider.of<FlwtchState>(context, listen: false).cwtch.RejectInvite(Provider.of<ContactInfoState>(context, listen: false).profileOnion, contact.identifier); // FIXME This flow is incrorect. Groups never just show up on the contact list anymore
Provider.of<ProfileInfoState>(context, listen: false).removeContact(contact.onion); Provider.of<ProfileInfoState>(context, listen: false).removeContact(contact.onion);
} else { } else {
Provider.of<FlwtchState>(context, listen: false).cwtch.BlockContact(Provider.of<ContactInfoState>(context, listen: false).profileOnion, contact.identifier); Provider.of<FlwtchState>(context, listen: false).cwtch.BlockContact(Provider.of<ContactInfoState>(context, listen: false).profileOnion, contact.identifier);

View File

@ -87,7 +87,7 @@ class _MessageListState extends State<MessageList> {
// Already includes MessageRow,, // Already includes MessageRow,,
return message.getWidget(context); return message.getWidget(context);
} else { } else {
return Text(''); //MessageLoadingBubble(); return MessageLoadingBubble();
} }
}, },
); );

View File

@ -1,9 +1,4 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import '../model.dart';
import 'package:intl/intl.dart';
import '../settings.dart';
class MessageLoadingBubble extends StatefulWidget { class MessageLoadingBubble extends StatefulWidget {
@override @override

View File

@ -15,6 +15,7 @@ import '../settings.dart';
class MessageRow extends StatefulWidget { class MessageRow extends StatefulWidget {
final Widget child; final Widget child;
MessageRow(this.child, {Key? key}) : super(key: key); MessageRow(this.child, {Key? key}) : super(key: key);
@override @override
@ -28,9 +29,12 @@ class MessageRowState extends State<MessageRow> with SingleTickerProviderStateMi
late Alignment _dragAlignment = Alignment.center; late Alignment _dragAlignment = Alignment.center;
Alignment _dragAffinity = Alignment.center; Alignment _dragAffinity = Alignment.center;
late int index;
@override @override
void initState() { void initState() {
super.initState(); super.initState();
index = Provider.of<MessageMetadata>(context, listen: false).messageIndex;
_controller = AnimationController(vsync: this); _controller = AnimationController(vsync: this);
_controller.addListener(() { _controller.addListener(() {
setState(() { setState(() {
@ -41,7 +45,9 @@ class MessageRowState extends State<MessageRow> with SingleTickerProviderStateMi
@override @override
void dispose() { void dispose() {
_controller.dispose(); if (_controller != null) {
_controller.dispose();
}
super.dispose(); super.dispose();
} }