From 61b838d34357b6dc002b7df1ff05de5139e59903 Mon Sep 17 00:00:00 2001 From: erinn Date: Wed, 7 Apr 2021 22:07:01 -0700 Subject: [PATCH] restoring sendmessage yay --- lib/cwtch/cwtch.dart | 11 +++++++++ lib/cwtch/cwtchNotifier.dart | 10 +++++++- lib/cwtch/ffi.dart | 48 ++++++++++++++++++++++++++++++++++++ lib/cwtch/gomobile.dart | 20 +++++++++++++++ lib/model.dart | 2 ++ lib/views/messageview.dart | 19 +++++++++++--- lib/widgets/contactrow.dart | 20 ++++++++++++--- lib/widgets/messagelist.dart | 17 +++++++++++++ 8 files changed, 140 insertions(+), 7 deletions(-) diff --git a/lib/cwtch/cwtch.dart b/lib/cwtch/cwtch.dart index 3bcb2e6..f0f992a 100644 --- a/lib/cwtch/cwtch.dart +++ b/lib/cwtch/cwtch.dart @@ -8,11 +8,20 @@ abstract class Cwtch { void CreateProfile(String nick, String pass); // ignore: non_constant_identifier_names void LoadProfiles(String pass); + + // todo: remove these // ignore: non_constant_identifier_names void SendProfileEvent(String onion, String jsonEvent); // ignore: non_constant_identifier_names void SendAppEvent(String jsonEvent); + // ignore: non_constant_identifier_names + void AcceptContact(String profileOnion, String contactHandle); + // ignore: non_constant_identifier_names + void BlockContact(String profileOnion, String contactHandle); + // ignore: non_constant_identifier_names + void DebugResetContact(String profileOnion, String contactHandle); + // ignore: non_constant_identifier_names Future ACNEvents(); // ignore: non_constant_identifier_names @@ -27,6 +36,8 @@ abstract class Cwtch { Future GetMessage(String profile, String handle, int index); // ignore: non_constant_identifier_names Future GetMessages(String profile, String handle, int start, int end); + // ignore: non_constant_identifier_names + void SendMessage(String profile, String handle, String message); void dispose(); } diff --git a/lib/cwtch/cwtchNotifier.dart b/lib/cwtch/cwtchNotifier.dart index d460422..3d614c9 100644 --- a/lib/cwtch/cwtchNotifier.dart +++ b/lib/cwtch/cwtchNotifier.dart @@ -43,11 +43,19 @@ class CwtchNotifier { //todo: stopgap, as lc-g is supposed to handle this print("PSC -> adding " + data["ProfileOnion"] + " :: " + data["RemotePeer"]); profileCN.getProfile(data["ProfileOnion"]).contactList.add( - ContactInfoState(profileOnion: data["ProfileOnion"], onion: data["RemotePeer"], nickname: data["name"], status: data["ConnectionState"], isBlocked: data["authorization"] == "blocked")); + ContactInfoState(profileOnion: data["ProfileOnion"], onion: data["RemotePeer"], nickname: data["name"], status: data["ConnectionState"], isBlocked: data["authorization"] == "blocked", isInvitation: data["authorization"] == "unknown")); } else { contact.status = data["ConnectionState"]; + if (data["authorization"] != null) { + contact.isInvitation = data["authorization"] == "unknown"; + contact.isBlocked = data["authorization"] == "blocked"; + } } break; + case "NewMessageFromPeer": + profileCN.getProfile(data["ProfileOnion"]).contactList.getContact(data["RemotePeer"]).unreadMessages++; + profileCN.getProfile(data["ProfileOnion"]).contactList.getContact(data["RemotePeer"]).totalMessages++; + break; case "AppError": print("New App Error: $data"); error.handleUpdate(data["Data"]); diff --git a/lib/cwtch/ffi.dart b/lib/cwtch/ffi.dart index 09f4f2e..b1c2699 100644 --- a/lib/cwtch/ffi.dart +++ b/lib/cwtch/ffi.dart @@ -19,6 +19,9 @@ typedef StartCwtchFn = void Function(Pointer dir, int len, Pointer t typedef void_from_string_string_function = Void Function(Pointer, Int32, Pointer, Int32); typedef VoidFromStringStringFn = void Function(Pointer, int, Pointer, int); +typedef void_from_string_string_string_function = Void Function(Pointer, Int32, Pointer, Int32, Pointer, Int32); +typedef VoidFromStringStringStringFn = void Function(Pointer, int, Pointer, int, Pointer, int); + typedef access_cwtch_eventbus_function = Void Function(); typedef NextEventFn = void Function(); @@ -249,4 +252,49 @@ class CwtchFfi implements Cwtch { final utf8json = json.toNativeUtf8(); SendAppBusEvent(utf8json, utf8json.length); } + + @override + // ignore: non_constant_identifier_names + void AcceptContact(String profileOnion, String contactHandle) { + var acceptContact = library.lookup>("c_AcceptContact"); + // ignore: non_constant_identifier_names + final AcceptContact = acceptContact.asFunction(); + final u1 = profileOnion.toNativeUtf8(); + final u2 = contactHandle.toNativeUtf8(); + AcceptContact(u1, u1.length, u2, u2.length); + } + + @override + // ignore: non_constant_identifier_names + void BlockContact(String profileOnion, String contactHandle) { + var blockContact = library.lookup>("c_BlockContact"); + // ignore: non_constant_identifier_names + final BlockContact = blockContact.asFunction(); + final u1 = profileOnion.toNativeUtf8(); + final u2 = contactHandle.toNativeUtf8(); + BlockContact(u1, u1.length, u2, u2.length); + } + + @override + // ignore: non_constant_identifier_names + void DebugResetContact(String profileOnion, String contactHandle) { + var debugResetContact = library.lookup>("c_DebugResetContact"); + // ignore: non_constant_identifier_names + final DebugResetContact = debugResetContact.asFunction(); + final u1 = profileOnion.toNativeUtf8(); + final u2 = contactHandle.toNativeUtf8(); + DebugResetContact(u1, u1.length, u2, u2.length); + } + + @override + // ignore: non_constant_identifier_names + void SendMessage(String profileOnion, String contactHandle, String message) { + var sendMessage = library.lookup>("c_SendMessage"); + // ignore: non_constant_identifier_names + final SendMessage = sendMessage.asFunction(); + final u1 = profileOnion.toNativeUtf8(); + final u2 = contactHandle.toNativeUtf8(); + final u3 = message.toNativeUtf8(); + SendMessage(u1, u1.length, u2, u2.length, u3, u3.length); + } } diff --git a/lib/cwtch/gomobile.dart b/lib/cwtch/gomobile.dart index ed7b616..ed38cc7 100644 --- a/lib/cwtch/gomobile.dart +++ b/lib/cwtch/gomobile.dart @@ -118,4 +118,24 @@ class CwtchGomobile implements Cwtch { @override void dispose() => {}; + + @override + void AcceptContact(String profileOnion, String contactHandle) { + cwtchPlatform.invokeMethod("AcceptContact", {"ProfileOnion": profileOnion, "handle": contactHandle}); + } + + @override + void BlockContact(String profileOnion, String contactHandle) { + cwtchPlatform.invokeMethod("BlockContact", {"ProfileOnion": profileOnion, "handle": contactHandle}); + } + + @override + void DebugResetContact(String profileOnion, String contactHandle) { + cwtchPlatform.invokeMethod("DebugResetContact", {"ProfileOnion": profileOnion, "handle": contactHandle}); + } + + @override + void SendMessage(String profileOnion, String contactHandle, String message) { + cwtchPlatform.invokeMethod("SendMessage", {"ProfileOnion": profileOnion, "handle": contactHandle, "message": message}); + } } diff --git a/lib/model.dart b/lib/model.dart index 9840fed..66bf826 100644 --- a/lib/model.dart +++ b/lib/model.dart @@ -138,6 +138,7 @@ class ProfileInfoState extends ChangeNotifier { print("decoding " + contactsJson); List contacts = jsonDecode(contactsJson); this._contacts.addAll(contacts.map((contact) { + print(contact["onion"]+" "+contact["picture"]+": "+contact["authorization"]+" -> " + (contact["authorization"] == "unknown" ? "invite" : "non-invite")); return ContactInfoState( profileOnion: this.onion, onion: contact["onion"], @@ -145,6 +146,7 @@ class ProfileInfoState extends ChangeNotifier { status: contact["status"], imagePath: contact["picture"], isBlocked: contact["authorization"] == "blocked", + isInvitation: contact["authorization"] == "unknown", savePeerHistory: contact["saveConversationHistory"], numMessages: contact["numMessages"], numUnread: contact["numUnread"]); diff --git a/lib/views/messageview.dart b/lib/views/messageview.dart index d81ec0e..4383f68 100644 --- a/lib/views/messageview.dart +++ b/lib/views/messageview.dart @@ -1,3 +1,5 @@ +import 'dart:convert'; + import 'package:flutter/material.dart'; import 'package:flutter_app/views/peersettingsview.dart'; import 'package:provider/provider.dart'; @@ -31,13 +33,20 @@ class _MessageViewState extends State { IconButton(icon: Icon(Icons.list), onPressed: _pushContactSettings), IconButton(icon: Icon(Icons.push_pin), onPressed: _pushContactSettings), IconButton(icon: Icon(Icons.settings), onPressed: _pushContactSettings), + IconButton(icon: Icon(Icons.bug_report_outlined), onPressed: _debugResetContact), ], ), - body: MessageList(), + body: Padding(padding: EdgeInsets.fromLTRB(8.0, 8.0, 8.0, 108.0), child: MessageList()), bottomSheet: _buildComposeBox(), ); } + void _debugResetContact() { + Provider.of(context, listen: false).cwtch.DebugResetContact( + Provider.of(context, listen: false).profileOnion, + Provider.of(context, listen: false).onion); + } + void _pushContactSettings() { Navigator.of(context).push(MaterialPageRoute( builder: (BuildContext bcontext) { @@ -57,9 +66,13 @@ class _MessageViewState extends State { } void _sendMessage() { - //ChatMessage cm = new ChatMessage(o: 1, d: ctrlrCompose.value.text); - //todo: merge: Provider.of(context).cwtch.SendMessage(widget.profile.onion, widget.conversationHandle, jsonEncode(cm)); + ChatMessage cm = new ChatMessage(o: 1, d: ctrlrCompose.value.text); + Provider.of(context, listen:false).cwtch.SendMessage( + Provider.of(context, listen:false).profileOnion, + Provider.of(context, listen:false).onion, + jsonEncode(cm)); ctrlrCompose.clear(); + Provider.of(context, listen:false).totalMessages++; } Widget _buildComposeBox() { diff --git a/lib/widgets/contactrow.dart b/lib/widgets/contactrow.dart index 0de405d..29cc273 100644 --- a/lib/widgets/contactrow.dart +++ b/lib/widgets/contactrow.dart @@ -35,10 +35,12 @@ class _ContactRowState extends State { ), ), trailing: contact.isInvitation != null && contact.isInvitation - ? Column(children: [Icon(Icons.favorite, color: Opaque.current().mainTextColor()), Icon(Icons.delete, color: Opaque.current().mainTextColor())]) - : Text("99+"), //(nb: Icons.create is a pencil and we use it for "edit", not create) + ? Wrap(direction: Axis.vertical, children: [ + IconButton(padding: EdgeInsets.zero, iconSize: 16, icon: Icon(Icons.favorite, color: Opaque.current().mainTextColor()), onPressed: _btnApprove,), + IconButton(padding: EdgeInsets.zero, iconSize: 16, icon: Icon(Icons.delete, color: Opaque.current().mainTextColor()), onPressed: _btnReject,)]) + : Text(contact.unreadMessages.toString()), //(nb: Icons.create is a pencil and we use it for "edit", not create) title: Text( - contact.nickname, + (contact.isInvitation ? "invite " : "non-invite ") + (contact.isBlocked ? "blokt" : "nonblokt"),//contact.nickname, style: Provider.of(context).biggerFont, ), subtitle: Text(contact.status), @@ -69,4 +71,16 @@ class _ContactRowState extends State { ), ); } + + void _btnApprove() { + Provider.of(context, listen: false).cwtch.AcceptContact( + Provider.of(context, listen: false).profileOnion, + Provider.of(context, listen: false).onion); + } + + void _btnReject() { + Provider.of(context, listen: false).cwtch.BlockContact( + Provider.of(context, listen: false).profileOnion, + Provider.of(context, listen: false).onion); + } } diff --git a/lib/widgets/messagelist.dart b/lib/widgets/messagelist.dart index 1b71f5c..48cb68f 100644 --- a/lib/widgets/messagelist.dart +++ b/lib/widgets/messagelist.dart @@ -1,4 +1,5 @@ import 'package:flutter/material.dart'; +import 'package:flutter/scheduler.dart'; import 'package:provider/provider.dart'; import '../model.dart'; @@ -10,9 +11,25 @@ class MessageList extends StatefulWidget { } class _MessageListState extends State { + ScrollController ctrlr1 = ScrollController(); + + @override + void initState() { + super.initState(); + WidgetsBinding.instance.addPostFrameCallback((_) => _scrollToBottom(true)); + } + + void _scrollToBottom(bool force) { + if (force || ctrlr1.position.pixels >= ctrlr1.position.maxScrollExtent - 3) { + ctrlr1.jumpTo(ctrlr1.position.maxScrollExtent); + } + } + @override Widget build(BuildContext outerContext) { + WidgetsBinding.instance.addPostFrameCallback((_) => _scrollToBottom(false)); return ListView.builder( + controller: ctrlr1, itemCount: Provider.of(context).totalMessages, itemBuilder: (context, index) { return MessageBubble(