Merge pull request 'Accept/Reject Group invites & other bug fixes' (#62) from groups into trunk
continuous-integration/drone/push Build is failing Details

Reviewed-on: #62
This commit is contained in:
erinn 2021-04-28 16:55:57 -07:00
commit 97b5709c75
10 changed files with 109 additions and 76 deletions

View File

@ -172,6 +172,11 @@ class MainActivity: FlutterActivity() {
val value = (call.argument("value") as? String) ?: "";
Cwtch.setGroupAttribute(profile, groupHandle, key, value);
}
"RejectInvite" -> {
val profile = (call.argument("ProfileOnion") as? String) ?: "";
val groupHandle = (call.argument("groupHandle") as? String) ?: "";
Cwtch.rejectInvite(profile, groupHandle);
}
else -> result.notImplemented()
}
}

Binary file not shown.

View File

@ -46,6 +46,8 @@ abstract class Cwtch {
void ImportBundle(String profile, String bundle);
// ignore: non_constant_identifier_names
void SetGroupAttribute(String profile, String groupHandle, String key, String value);
// ignore: non_constant_identifier_names
void RejectInvite(String profileOnion, String groupHandle);
void dispose();
}

View File

@ -65,8 +65,7 @@ class CwtchNotifier {
case "NewMessageFromGroup":
profileCN.getProfile(data["ProfileOnion"]).contactList.getContact(data["GroupID"]).unreadMessages++;
profileCN.getProfile(data["ProfileOnion"]).contactList.getContact(data["GroupID"]).totalMessages++;
// TODO exception is called in the case of groups.
profileCN.getProfile(data["ProfileOnion"]).contactList.updateLastMessageTime(data["RemotePeer"], DateTime.now());
profileCN.getProfile(data["ProfileOnion"]).contactList.updateLastMessageTime(data["GroupID"], DateTime.now());
break;
case "AppError":
print("New App Error: $data");
@ -95,16 +94,15 @@ class CwtchNotifier {
break;
case "NewGroupInvite":
print("new group invite: $data");
// TODO Add Group Dynamically
dynamic groupInvite = jsonDecode(data["GroupInvite"]);
profileCN.getProfile(data["ProfileOnion"]).contactList.add(ContactInfoState(
"",
groupInvite["GroupID"],
isInvitation: true,
imagePath: data["PicturePath"],
nickname: groupInvite["GroupName"],
server: groupInvite["ServerHost"],
isGroup: true));
profileCN.getProfile(data["ProfileOnion"]).contactList.add(ContactInfoState(data["ProfileOnion"], groupInvite["GroupID"],
isInvitation: true, imagePath: data["PicturePath"], nickname: groupInvite["GroupName"], server: groupInvite["ServerHost"], isGroup: true, lastMessageTime: DateTime.now()));
profileCN.getProfile(data["ProfileOnion"]).contactList.updateLastMessageTime(groupInvite["GroupID"], DateTime.now());
break;
case "AcceptGroupInvite":
print("accept group invite: $data");
profileCN.getProfile(data["ProfileOnion"]).contactList.getContact(data["GroupID"]).isInvitation = false;
profileCN.getProfile(data["ProfileOnion"]).contactList.updateLastMessageTime(data["GroupID"], DateTime.now());
break;
case "ServerStateChange":
print("server state change: $data");

View File

@ -332,4 +332,15 @@ class CwtchFfi implements Cwtch {
final u4 = value.toNativeUtf8();
SetGroupAttribute(u1, u1.length, u2, u2.length, u3, u3.length, u4, u4.length);
}
@override
// ignore: non_constant_identifier_names
void RejectInvite(String profileOnion, String groupHandle) {
var rejectInvite = library.lookup<NativeFunction<string_string_to_void_function>>("c_RejectInvite");
// ignore: non_constant_identifier_names
final RejectInvite = rejectInvite.asFunction<VoidFromStringStringFn>();
final u1 = profileOnion.toNativeUtf8();
final u2 = groupHandle.toNativeUtf8();
RejectInvite(u1, u1.length, u2, u2.length);
}
}

View File

@ -159,4 +159,10 @@ class CwtchGomobile implements Cwtch {
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, String groupHandle) {
cwtchPlatform.invokeMethod("RejectInvite", {"ProfileOnion": profileOnion, "handle": groupHandle});
}
}

View File

@ -141,9 +141,7 @@ class ProfileInfoState extends ChangeNotifier {
if (contactsJson != null && contactsJson != "" && contactsJson != "null") {
List<dynamic> contacts = jsonDecode(contactsJson);
this._contacts.addAll(contacts.map((contact) {
return ContactInfoState(
this.onion,
contact["onion"],
return ContactInfoState(this.onion, contact["onion"],
nickname: contact["name"],
status: contact["status"],
imagePath: contact["picture"],
@ -203,6 +201,14 @@ class ProfileInfoState extends ChangeNotifier {
notifyListeners();
}
// Remove a contact from a list. Currently only used when rejecting a group invitation.
// Eventually will also be used for other removals.
void removeContact(String handle) {
int idx = this.contactList._contacts.indexWhere((element) => element.onion == handle);
this.contactList._contacts.removeAt(idx);
notifyListeners();
}
ContactListState get contactList => this._contacts;
ServerListState get serverList => this._servers;
@ -233,7 +239,7 @@ class ContactInfoState extends ChangeNotifier {
ContactInfoState(
this.profileOnion,
this.onion,{
this.onion, {
nickname = "",
isGroup = false,
isInvitation = false,

View File

@ -105,20 +105,18 @@ class _MessageViewState extends State<MessageView> {
onSubmitted: _sendMessage,
)),
SizedBox(
width: 100,
height: 90,
child: Padding(
padding: EdgeInsets.fromLTRB(2, 2, 2, 2),
child: ElevatedButton(
child: Icon(Icons.send, color: Provider.of<Settings>(context).theme.mainTextColor()),
style: ButtonStyle(
fixedSize: MaterialStateProperty.all(Size(86, 40)),
backgroundColor: MaterialStateProperty.all(Provider.of<Settings>(context).theme.defaultButtonColor()),
),
onPressed: _sendMessage,
)
)
),
width: 100,
height: 90,
child: Padding(
padding: EdgeInsets.fromLTRB(2, 2, 2, 2),
child: ElevatedButton(
child: Icon(Icons.send, color: Provider.of<Settings>(context).theme.mainTextColor()),
style: ButtonStyle(
fixedSize: MaterialStateProperty.all(Size(86, 40)),
backgroundColor: MaterialStateProperty.all(Provider.of<Settings>(context).theme.defaultButtonColor()),
),
onPressed: _sendMessage,
))),
],
),
);

View File

@ -109,9 +109,13 @@ class _ContactRowState extends State<ContactRow> {
}
void _btnReject() {
Provider.of<FlwtchState>(context, listen: false)
.cwtch
.BlockContact(Provider.of<ContactInfoState>(context, listen: false).profileOnion, Provider.of<ContactInfoState>(context, listen: false).onion);
ContactInfoState contact = Provider.of<ContactInfoState>(context, listen: false);
if (contact.isGroup == true) {
Provider.of<FlwtchState>(context, listen: false).cwtch.RejectInvite(Provider.of<ContactInfoState>(context, listen: false).profileOnion, contact.onion);
Provider.of<ProfileInfoState>(context, listen: false).removeContact(contact.onion);
} else {
Provider.of<FlwtchState>(context, listen: false).cwtch.BlockContact(Provider.of<ContactInfoState>(context, listen: false).profileOnion, contact.onion);
}
}
String dateToNiceString(DateTime date) {

View File

@ -26,52 +26,55 @@ class _MessageBubbleState extends State<MessageBubble> {
}
return LayoutBuilder(builder: (context, constraints) {
//print(constraints.toString()+", "+constraints.maxWidth.toString());
return Container(child:Container(
decoration: BoxDecoration(
color: fromMe ? Provider.of<Settings>(context).theme.messageFromMeBackgroundColor() : Provider.of<Settings>(context).theme.messageFromOtherBackgroundColor(),
border: Border.all(color: fromMe ? Provider.of<Settings>(context).theme.messageFromMeBackgroundColor() : Provider.of<Settings>(context).theme.messageFromOtherBackgroundColor(), width: 1),
borderRadius: BorderRadius.only(
topLeft: Radius.circular(borderRadiousEh),
topRight: Radius.circular(borderRadiousEh),
bottomLeft: fromMe ? Radius.circular(borderRadiousEh) : Radius.zero,
bottomRight: fromMe ? Radius.zero : Radius.circular(borderRadiousEh),
),
),
child: Padding(
padding: EdgeInsets.all(9.0),
child: Column(
crossAxisAlignment: fromMe ? CrossAxisAlignment.end : CrossAxisAlignment.start,
mainAxisAlignment: fromMe ? MainAxisAlignment.end : MainAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
//Flexible(
//fit: BoxFit.contain,
SelectableText(
(Provider.of<MessageState>(context).message ?? "") + '\u202F',
key: Key(myKey),
focusNode: _focus,
style: TextStyle(
color: fromMe ? Provider.of<Settings>(context).theme.messageFromMeTextColor() : Provider.of<Settings>(context).theme.messageFromOtherTextColor(),
return Container(
child: Container(
decoration: BoxDecoration(
color: fromMe ? Provider.of<Settings>(context).theme.messageFromMeBackgroundColor() : Provider.of<Settings>(context).theme.messageFromOtherBackgroundColor(),
border:
Border.all(color: fromMe ? Provider.of<Settings>(context).theme.messageFromMeBackgroundColor() : Provider.of<Settings>(context).theme.messageFromOtherBackgroundColor(), width: 1),
borderRadius: BorderRadius.only(
topLeft: Radius.circular(borderRadiousEh),
topRight: Radius.circular(borderRadiousEh),
bottomLeft: fromMe ? Radius.circular(borderRadiousEh) : Radius.zero,
bottomRight: fromMe ? Radius.zero : Radius.circular(borderRadiousEh),
),
textAlign: TextAlign.left,
textWidthBasis: TextWidthBasis.longestLine,
),
Center(widthFactor: 1.0, child: Row(
mainAxisSize: MainAxisSize.min,
children: [
Text(prettyDate,
style: TextStyle(
fontSize: 9.0,
color: fromMe ? Provider.of<Settings>(context).theme.messageFromMeTextColor() : Provider.of<Settings>(context).theme.messageFromOtherTextColor(),
),
textAlign: fromMe ? TextAlign.right : TextAlign.left),
Provider.of<MessageState>(context).ackd
? Icon(Icons.check_circle_outline, color: Provider.of<Settings>(context).theme.messageFromMeTextColor(), size: 12)
: Icon(Icons.hourglass_bottom_outlined, color: Provider.of<Settings>(context).theme.messageFromMeTextColor(), size: 12)
],
)
)])),
));
child: Padding(
padding: EdgeInsets.all(9.0),
child: Column(
crossAxisAlignment: fromMe ? CrossAxisAlignment.end : CrossAxisAlignment.start,
mainAxisAlignment: fromMe ? MainAxisAlignment.end : MainAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
//Flexible(
//fit: BoxFit.contain,
SelectableText(
(Provider.of<MessageState>(context).message ?? "") + '\u202F',
key: Key(myKey),
focusNode: _focus,
style: TextStyle(
color: fromMe ? Provider.of<Settings>(context).theme.messageFromMeTextColor() : Provider.of<Settings>(context).theme.messageFromOtherTextColor(),
),
textAlign: TextAlign.left,
textWidthBasis: TextWidthBasis.longestLine,
),
Center(
widthFactor: 1.0,
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
Text(prettyDate,
style: TextStyle(
fontSize: 9.0,
color: fromMe ? Provider.of<Settings>(context).theme.messageFromMeTextColor() : Provider.of<Settings>(context).theme.messageFromOtherTextColor(),
),
textAlign: fromMe ? TextAlign.right : TextAlign.left),
Provider.of<MessageState>(context).ackd
? Icon(Icons.check_circle_outline, color: Provider.of<Settings>(context).theme.messageFromMeTextColor(), size: 12)
: Icon(Icons.hourglass_bottom_outlined, color: Provider.of<Settings>(context).theme.messageFromMeTextColor(), size: 12)
],
))
]))));
});
}
}