Persist rejection action #166
|
@ -1 +1 @@
|
|||
v0.0.2-49-g6a0e839-2021-06-02-19-40
|
||||
v0.0.2-58-gfddfd41-2021-06-10-18-36
|
|
@ -129,6 +129,13 @@ class MainActivity: FlutterActivity() {
|
|||
val end = (call.argument("end") as? Long) ?: 0;
|
||||
result.success(Cwtch.getMessages(profile, handle, start, end))
|
||||
}
|
||||
"UpdateMessageFlags" -> {
|
||||
val profile = (call.argument("profile") as? String) ?: "";
|
||||
val handle = (call.argument("contact") as? String) ?: "";
|
||||
val midx = (call.argument("midx") as? Long) ?: 0;
|
||||
val flags = (call.argument("flags") as? Long) ?: 0;
|
||||
Cwtch.updateMessageFlags(profile, handle, midx, flags);
|
||||
}
|
||||
"AcceptContact" -> {
|
||||
val profile = (call.argument("ProfileOnion") as? String) ?: "";
|
||||
val handle = (call.argument("handle") as? String) ?: "";
|
||||
|
|
Binary file not shown.
|
@ -38,6 +38,8 @@ abstract class Cwtch {
|
|||
// ignore: non_constant_identifier_names
|
||||
Future<dynamic> GetMessage(String profile, String handle, int index);
|
||||
// ignore: non_constant_identifier_names
|
||||
void UpdateMessageFlags(String profile, String handle, int index, int flags);
|
||||
// ignore: non_constant_identifier_names
|
||||
Future<dynamic> GetMessages(String profile, String handle, int start, int end);
|
||||
// ignore: non_constant_identifier_names
|
||||
void SendMessage(String profile, String handle, String message);
|
||||
|
|
|
@ -178,23 +178,24 @@ class CwtchNotifier {
|
|||
profileCN.getProfile(data["ProfileOnion"])?.replaceServers(data["ServerList"]);
|
||||
break;
|
||||
case "NewGroup":
|
||||
print("new group invite: $data");
|
||||
print("new group: $data");
|
||||
String invite = data["GroupInvite"].toString();
|
||||
if (invite.startsWith("torv3")) {
|
||||
String inviteJson = new String.fromCharCodes(base64Decode(invite.substring(5)));
|
||||
dynamic groupInvite = jsonDecode(inviteJson);
|
||||
print("new group invite: $groupInvite");
|
||||
print("group invite: $groupInvite");
|
||||
|
||||
// Retrieve Server Status from Cache...
|
||||
String status = "";
|
||||
ServerInfoState? serverInfoState = profileCN.getProfile(data["ProfileOnion"])?.serverList.getServer(groupInvite["ServerHost"]);
|
||||
ServerInfoState? serverInfoState = profileCN.getProfile(data["ProfileOnion"])!.serverList.getServer(groupInvite["ServerHost"]);
|
||||
if (serverInfoState != null) {
|
||||
print("Got server status: " + serverInfoState.status);
|
||||
status = serverInfoState.status;
|
||||
}
|
||||
|
||||
if (profileCN.getProfile(data["ProfileOnion"])?.contactList.getContact(groupInvite["GroupID"]) == null) {
|
||||
profileCN.getProfile(data["ProfileOnion"])?.contactList.add(ContactInfoState(data["ProfileOnion"], groupInvite["GroupID"],
|
||||
isInvitation: true,
|
||||
isInvitation: false,
|
||||
imagePath: data["PicturePath"],
|
||||
nickname: groupInvite["GroupName"],
|
||||
server: groupInvite["ServerHost"],
|
||||
|
|
|
@ -27,6 +27,9 @@ typedef VoidFromStringStringStringFn = void Function(Pointer<Utf8>, int, Pointer
|
|||
typedef void_from_string_string_string_string_function = Void Function(Pointer<Utf8>, Int32, Pointer<Utf8>, Int32, Pointer<Utf8>, Int32, Pointer<Utf8>, Int32);
|
||||
typedef VoidFromStringStringStringStringFn = void Function(Pointer<Utf8>, int, Pointer<Utf8>, int, Pointer<Utf8>, int, Pointer<Utf8>, int);
|
||||
|
||||
typedef void_from_string_string_int_int_function = Void Function(Pointer<Utf8>, Int32, Pointer<Utf8>, Int32, Int64, Int64);
|
||||
typedef VoidFromStringStringIntIntFn = void Function(Pointer<Utf8>, int, Pointer<Utf8>, int, int, int);
|
||||
|
||||
typedef access_cwtch_eventbus_function = Void Function();
|
||||
typedef NextEventFn = void Function();
|
||||
|
||||
|
@ -384,4 +387,14 @@ class CwtchFfi implements Cwtch {
|
|||
final u2 = groupHandle.toNativeUtf8();
|
||||
RejectInvite(u1, u1.length, u2, u2.length);
|
||||
}
|
||||
|
||||
@override
|
||||
void UpdateMessageFlags(String profile, String handle, int index, int flags) {
|
||||
var updateMessageFlagsC = library.lookup<NativeFunction<void_from_string_string_int_int_function>>("c_UpdateMessageFlags");
|
||||
// ignore: non_constant_identifier_names
|
||||
final updateMessageFlags = updateMessageFlagsC.asFunction<VoidFromStringStringIntIntFn>();
|
||||
final utf8profile = profile.toNativeUtf8();
|
||||
final utf8handle = handle.toNativeUtf8();
|
||||
updateMessageFlags(utf8profile, utf8profile.length, utf8handle, utf8handle.length, index, flags);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import 'dart:convert';
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:cwtch/config.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
|
@ -187,4 +186,10 @@ class CwtchGomobile implements Cwtch {
|
|||
void LeaveGroup(String profileOnion, String groupHandle) {
|
||||
cwtchPlatform.invokeMethod("LeaveGroup", {"ProfileOnion": profileOnion, "handle": groupHandle});
|
||||
}
|
||||
|
||||
@override
|
||||
void UpdateMessageFlags(String profile, String handle, int index, int flags) {
|
||||
print("gomobile.dart UpdateMessageFlags " + index.toString());
|
||||
cwtchPlatform.invokeMethod("UpdateMessageFlags", {"profile": profile, "contact": handle, "index": index, "flags": flags});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/// Flutter icons MyFlutterApp
|
||||
/// Copyright (C) 2021 by original authors @ fluttericon.com, fontello.com
|
||||
/// Flutter icons CwtchIcons
|
||||
/// Copyright (C) 2021 by Open Privacy Research Society via fluttericon.com, fontello.com
|
||||
/// This font was generated by FlutterIcon.com, which is derived from Fontello.
|
||||
///
|
||||
/// To use this font, place it in your fonts/ directory and include the
|
||||
|
@ -102,8 +102,9 @@ class CwtchIcons {
|
|||
static const IconData add_group = IconData(0xe84e, fontFamily: _kFontFam, fontPackage: _kFontPkg);
|
||||
static const IconData add_peer = IconData(0xe84f, fontFamily: _kFontFam, fontPackage: _kFontPkg);
|
||||
static const IconData add_24px = IconData(0xe850, fontFamily: _kFontFam, fontPackage: _kFontPkg);
|
||||
static const IconData address_copy_2 = IconData(0xe852, fontFamily: _kFontFam, fontPackage: _kFontPkg);
|
||||
static const IconData address = IconData(0xe856, fontFamily: _kFontFam, fontPackage: _kFontPkg);
|
||||
static const IconData send_invite = IconData(0xe888, fontFamily: _kFontFam, fontPackage: _kFontPkg);
|
||||
static const IconData copy_address = IconData(0xe889, fontFamily: _kFontFam, fontPackage: _kFontPkg);
|
||||
static const IconData leave_group = IconData(0xe88a, fontFamily: _kFontFam, fontPackage: _kFontPkg);
|
||||
static const IconData leave_chat = IconData(0xe88b, fontFamily: _kFontFam, fontPackage: _kFontPkg);
|
||||
}
|
||||
|
|
|
@ -183,7 +183,7 @@ class ProfileInfoState extends ChangeNotifier {
|
|||
|
||||
// Parse out the server list json into our server info state struct...
|
||||
void replaceServers(String serversJson) {
|
||||
if (serversJson != null && serversJson != "" && serversJson != "null") {
|
||||
if (serversJson != "" && serversJson != "null") {
|
||||
print("got servers $serversJson");
|
||||
List<dynamic> servers = jsonDecode(serversJson);
|
||||
this._servers.replace(servers.map((server) {
|
||||
|
@ -382,6 +382,7 @@ class MessageState extends ChangeNotifier {
|
|||
late String _inviteNick;
|
||||
late DateTime _timestamp;
|
||||
late String _senderOnion;
|
||||
late int _flags;
|
||||
String? _senderImage;
|
||||
late String _signature = "";
|
||||
late bool _ackd = false;
|
||||
|
@ -402,6 +403,12 @@ class MessageState extends ChangeNotifier {
|
|||
get message => this._message;
|
||||
get overlay => this._overlay;
|
||||
get timestamp => this._timestamp;
|
||||
int get flags => this._flags;
|
||||
set flags(int newVal) {
|
||||
this._flags = newVal;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
bool get ackd => this._ackd;
|
||||
bool get error => this._error;
|
||||
bool get malformed => this._malformed;
|
||||
|
@ -450,6 +457,7 @@ class MessageState extends ChangeNotifier {
|
|||
this._timestamp = DateTime.tryParse(messageWrapper['Timestamp'])!;
|
||||
this._senderOnion = messageWrapper['PeerID'];
|
||||
this._senderImage = messageWrapper['ContactImage'];
|
||||
this._flags = int.parse(messageWrapper['Flags'].toString(), radix: 2);
|
||||
|
||||
// If this is a group, store the signature
|
||||
if (contactHandle.length == 32) {
|
||||
|
|
|
@ -119,7 +119,11 @@ class _AddContactViewState extends State<AddContactView> {
|
|||
CwtchButtonTextField(
|
||||
controller: ctrlrOnion,
|
||||
onPressed: _copyOnion,
|
||||
icon: Icon(CwtchIcons.copy_address),
|
||||
readonly: true,
|
||||
icon: Icon(
|
||||
CwtchIcons.address_copy_2,
|
||||
size: 32,
|
||||
),
|
||||
tooltip: AppLocalizations.of(context)!.copyBtn,
|
||||
),
|
||||
SizedBox(
|
||||
|
|
|
@ -11,6 +11,7 @@ import 'package:cwtch/widgets/textfield.dart';
|
|||
import 'package:provider/provider.dart';
|
||||
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
||||
|
||||
import '../cwtch_icons_icons.dart';
|
||||
import '../main.dart';
|
||||
import '../opaque.dart';
|
||||
import '../settings.dart';
|
||||
|
@ -122,7 +123,11 @@ class _AddEditProfileViewState extends State<AddEditProfileView> {
|
|||
CwtchButtonTextField(
|
||||
controller: ctrlrOnion,
|
||||
onPressed: _copyOnion,
|
||||
icon: Icon(Icons.copy),
|
||||
readonly: true,
|
||||
icon: Icon(
|
||||
CwtchIcons.address_copy_2,
|
||||
size: 32,
|
||||
),
|
||||
tooltip: AppLocalizations.of(context)!.copyBtn,
|
||||
)
|
||||
])),
|
||||
|
|
|
@ -28,6 +28,7 @@ class _CwtchButtonTextFieldState extends State<CwtchButtonTextField> {
|
|||
suffixIcon: IconButton(
|
||||
onPressed: widget.onPressed,
|
||||
icon: widget.icon,
|
||||
padding: EdgeInsets.fromLTRB(0.0, 4.0, 2.0, 2.0),
|
||||
tooltip: widget.tooltip,
|
||||
enableFeedback: true,
|
||||
color: theme.current().mainTextColor(),
|
||||
|
|
|
@ -22,15 +22,17 @@ class InvitationBubble extends StatefulWidget {
|
|||
|
||||
class InvitationBubbleState extends State<InvitationBubble> {
|
||||
bool rejected = false;
|
||||
bool isAccepted = false;
|
||||
FocusNode _focus = FocusNode();
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
var fromMe = Provider.of<MessageState>(context).senderOnion == Provider.of<ProfileInfoState>(context).onion;
|
||||
var isGroup = Provider.of<MessageState>(context).overlay == 101;
|
||||
var isAccepted = Provider.of<ProfileInfoState>(context).contactList.getContact(Provider.of<MessageState>(context).inviteTarget) != null;
|
||||
isAccepted = Provider.of<ProfileInfoState>(context).contactList.getContact(Provider.of<MessageState>(context).inviteTarget) != null;
|
||||
var prettyDate = "";
|
||||
var borderRadiousEh = 15.0;
|
||||
rejected = Provider.of<MessageState>(context).flags & 0x01 == 0x01;
|
||||
var myKey = Provider.of<MessageState>(context).profileOnion + "::" + Provider.of<MessageState>(context).contactHandle + "::" + Provider.of<MessageState>(context).messageIndex.toString();
|
||||
|
||||
if (Provider.of<MessageState>(context).timestamp != null) {
|
||||
|
@ -54,8 +56,6 @@ class InvitationBubbleState extends State<InvitationBubble> {
|
|||
child: SelectableText(senderDisplayStr + '\u202F',
|
||||
style: TextStyle(fontSize: 9.0, color: fromMe ? Provider.of<Settings>(context).theme.messageFromMeTextColor() : Provider.of<Settings>(context).theme.messageFromOtherTextColor())));
|
||||
|
||||
// todo: translations
|
||||
|
||||
// If we receive an invite for ourselves, treat it as a bug. The UI no longer allows this so it could have only come from
|
||||
// some kind of malfeasance.
|
||||
var selfInvite = Provider.of<MessageState>(context).inviteNick == Provider.of<ProfileInfoState>(context).onion;
|
||||
|
@ -120,22 +120,21 @@ class InvitationBubbleState extends State<InvitationBubble> {
|
|||
}
|
||||
|
||||
void _btnReject() {
|
||||
//todo: how should we track inline invite rejections?
|
||||
setState(() => this.rejected = true);
|
||||
setState(() {
|
||||
var profileOnion = Provider.of<ProfileInfoState>(context, listen: false).onion;
|
||||
var contact = Provider.of<ContactInfoState>(context, listen: false).onion;
|
||||
var idx = Provider.of<MessageState>(context, listen: false).messageIndex;
|
||||
Provider.of<FlwtchState>(context, listen: false).cwtch.UpdateMessageFlags(profileOnion, contact, idx, Provider.of<MessageState>(context, listen: false).flags | 0x01);
|
||||
Provider.of<MessageState>(context).flags |= 0x01;
|
||||
});
|
||||
}
|
||||
|
||||
void _btnAccept() {
|
||||
setState(() {
|
||||
var profileOnion = Provider.of<ProfileInfoState>(context, listen: false).onion;
|
||||
if (Provider.of<MessageState>(context, listen: false).overlay == 100) {
|
||||
final setPeerAttribute = {
|
||||
"EventType": "AddContact",
|
||||
"Data": {"ImportString": Provider.of<MessageState>(context, listen: false).message},
|
||||
};
|
||||
final setPeerAttributeJson = jsonEncode(setPeerAttribute);
|
||||
Provider.of<FlwtchState>(context, listen: false).cwtch.SendProfileEvent(profileOnion, setPeerAttributeJson);
|
||||
} else {
|
||||
Provider.of<FlwtchState>(context, listen: false).cwtch.ImportBundle(profileOnion, Provider.of<MessageState>(context, listen: false).message);
|
||||
}
|
||||
isAccepted = true;
|
||||
});
|
||||
}
|
||||
|
||||
// Construct an invite chrome for the sender
|
||||
|
|
|
@ -15,7 +15,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev
|
|||
# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
|
||||
# Read more about iOS versioning at
|
||||
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
|
||||
version: 1.0.0+10
|
||||
version: 1.0.0+11
|
||||
|
||||
environment:
|
||||
sdk: ">=2.12.0 <3.0.0"
|
||||
|
|
Loading…
Reference in New Issue