diff --git a/lib/cwtch/cwtchNotifier.dart b/lib/cwtch/cwtchNotifier.dart index a8ed7c6..89565b4 100644 --- a/lib/cwtch/cwtchNotifier.dart +++ b/lib/cwtch/cwtchNotifier.dart @@ -1,4 +1,5 @@ import 'dart:convert'; +import 'package:cwtch/models/servers.dart'; import 'package:cwtch/notification_manager.dart'; import 'package:provider/provider.dart'; @@ -49,9 +50,17 @@ class CwtchNotifier { )); break; case "GroupCreated": + + // Retrieve Server Status from Cache... + String status = ""; + ServerInfoState? serverInfoState = profileCN.getProfile(data["ProfileOnion"])?.serverList.getServer(data["GroupServer"]); + if (serverInfoState != null) { + status = serverInfoState.status; + } + if (profileCN.getProfile(data["ProfileOnion"])?.contactList.getContact(data["GroupID"]) == null) { profileCN.getProfile(data["ProfileOnion"])?.contactList.add(ContactInfoState(data["ProfileOnion"], data["GroupID"], - isInvitation: false, imagePath: data["PicturePath"], nickname: data["GroupName"], server: data["GroupServer"], isGroup: true, lastMessageTime: DateTime.now())); + isInvitation: false, imagePath: data["PicturePath"], nickname: data["GroupName"], status: status, server: data["GroupServer"], isGroup: true, lastMessageTime: DateTime.now())); profileCN.getProfile(data["ProfileOnion"])?.contactList.updateLastMessageTime(data["GroupID"], DateTime.now()); } break; @@ -175,9 +184,23 @@ class CwtchNotifier { String inviteJson = new String.fromCharCodes(base64Decode(invite.substring(5))); dynamic groupInvite = jsonDecode(inviteJson); print("new group invite: $groupInvite"); + + // Retrieve Server Status from Cache... + String status = ""; + ServerInfoState? serverInfoState = profileCN.getProfile(data["ProfileOnion"])?.serverList.getServer(groupInvite["ServerHost"]); + if (serverInfoState != null) { + 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, imagePath: data["PicturePath"], nickname: groupInvite["GroupName"], server: groupInvite["ServerHost"], isGroup: true, lastMessageTime: DateTime.now())); + isInvitation: true, + imagePath: data["PicturePath"], + nickname: groupInvite["GroupName"], + server: groupInvite["ServerHost"], + status: status, + isGroup: true, + lastMessageTime: DateTime.now())); profileCN.getProfile(data["ProfileOnion"])?.contactList.updateLastMessageTime(groupInvite["GroupID"], DateTime.now()); } } @@ -189,6 +212,8 @@ class CwtchNotifier { break; case "ServerStateChange": print("server state change: $data"); + // Update the Server Cache + profileCN.getProfile(data["ProfileOnion"])?.updateServerStatusCache(data["GroupServer"], data["ConnectionState"]); profileCN.getProfile(data["ProfileOnion"])?.contactList.contacts.forEach((contact) { if (contact.isGroup == true && contact.server == data["GroupServer"]) { contact.status = data["ConnectionState"]; @@ -205,6 +230,16 @@ class CwtchNotifier { print("unhandled set group attribute event: $type $data"); } break; + case "NewRetValMessageFromPeer": + if (data["Path"] == "name") { + // Update locally on the UI... + if (profileCN.getProfile(data["ProfileOnion"])?.contactList.getContact(data["RemotePeer"]) != null) { + profileCN.getProfile(data["ProfileOnion"])?.contactList.getContact(data["RemotePeer"])!.nickname = data["Data"]; + } + } else { + print("unhandled peer attribute event: $type $data"); + } + break; default: print("unhandled event: $type $data"); } diff --git a/lib/main.dart b/lib/main.dart index 4e1f94d..bfde1c1 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -43,7 +43,6 @@ class FlwtchState extends State { String selectedConversation = ""; var columns = [1]; // default or 'single column' mode //var columns = [1, 1, 2]; - late AppModel appStatus; late ProfileListState profs; @override @@ -69,8 +68,6 @@ class FlwtchState extends State { cwtchInit = true; }); }); - - appStatus = AppModel(cwtch: cwtch); } ChangeNotifierProvider getTorStatusProvider() => ChangeNotifierProvider.value(value: globalTorStatus); diff --git a/lib/model.dart b/lib/model.dart index d7630ef..f5f80d0 100644 --- a/lib/model.dart +++ b/lib/model.dart @@ -190,9 +190,16 @@ class ProfileInfoState extends ChangeNotifier { // TODO Keys... return ServerInfoState(onion: server["onion"], status: server["status"]); })); + notifyListeners(); } } + // + void updateServerStatusCache(String server, String status) { + this._servers.updateServerCache(server, status); + notifyListeners(); + } + // Getters and Setters for Online Status bool get isOnline => this._online; set isOnline(bool newValue) { @@ -470,37 +477,3 @@ class MessageState extends ChangeNotifier { }); } } - -///////////// -/// ACN /// -///////////// - -class AppModel { - final Cwtch cwtch; - AppModel({required this.cwtch}); - - Stream contactEvents() async* { - while (true) { - String event = await cwtch.ContactEvents(); - if (event != "") { - print(event); - yield event; - } else { - print("TEST TEST FAIL TEST FAIL 123"); - await Future.delayed(Duration(seconds: 1)); - } - } - } - - Stream torStatus() async* { - while (true) { - String event = await cwtch.ACNEvents(); - if (event != "") { - yield event; - } else { - print("TOR TEST TEST FAIL TEST FAIL 123"); - await Future.delayed(Duration(seconds: 1)); - } - } - } -} diff --git a/lib/models/servers.dart b/lib/models/servers.dart index 3bd62b7..6996aed 100644 --- a/lib/models/servers.dart +++ b/lib/models/servers.dart @@ -14,6 +14,16 @@ class ServerListState extends ChangeNotifier { return idx >= 0 ? _servers[idx] : null; } + void updateServerCache(String onion, String status) { + int idx = _servers.indexWhere((element) => element.onion == onion); + if (idx >= 0) { + _servers[idx] = ServerInfoState(onion: onion, status: status); + } else { + print("Tried to update server cache without a starting state...this is probably an error"); + } + notifyListeners(); + } + List get servers => _servers.sublist(0); //todo: copy?? dont want caller able to bypass changenotifier } diff --git a/lib/widgets/contactrow.dart b/lib/widgets/contactrow.dart index acf8a34..4727262 100644 --- a/lib/widgets/contactrow.dart +++ b/lib/widgets/contactrow.dart @@ -93,7 +93,8 @@ class _ContactRowState extends State { MaterialPageRoute( builder: (BuildContext builderContext) { // assert we have an actual profile... - var profile = Provider.of(builderContext, listen: false).profs.getProfile(profileOnion)!; + // We need to listen for updates to the profile in order to update things like invitation message bubbles. + var profile = Provider.of(builderContext).profs.getProfile(profileOnion)!; return MultiProvider( providers: [ ChangeNotifierProvider.value(value: profile), diff --git a/lib/widgets/messagelist.dart b/lib/widgets/messagelist.dart index fc5b728..dd89b23 100644 --- a/lib/widgets/messagelist.dart +++ b/lib/widgets/messagelist.dart @@ -40,6 +40,7 @@ class _MessageListState extends State { create: (x) => MessageState( context: itemBuilderContext, profileOnion: Provider.of(outerContext, listen: false).onion, + // We don't want to listen for updates to the contact handle... contactHandle: Provider.of(x, listen: false).onion, messageIndex: trueIndex, ), diff --git a/lib/widgets/torstatuslabel.dart b/lib/widgets/torstatuslabel.dart deleted file mode 100644 index 92c14fb..0000000 --- a/lib/widgets/torstatuslabel.dart +++ /dev/null @@ -1,27 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:provider/provider.dart'; -import '../main.dart'; -import 'package:flutter_gen/gen_l10n/app_localizations.dart'; - -class TorStatusLabel extends StatefulWidget { - @override - _TorStatusState createState() => _TorStatusState(); -} - -class _TorStatusState extends State { - String status = ""; - - @override - Widget build(BuildContext context) { - return Builder( - builder: (context2) => StreamBuilder( - stream: Provider.of(context).appStatus.torStatus(), - builder: (BuildContext context, AsyncSnapshot snapshot) { - return Text( - snapshot.hasData ? snapshot.data! : AppLocalizations.of(context)!.loadingTor, - style: Theme.of(context).textTheme.headline4, - ); - }, - )); - } -}