diff --git a/LIBCWTCH-GO.version b/LIBCWTCH-GO.version index 078b0378..2ea31b78 100644 --- a/LIBCWTCH-GO.version +++ b/LIBCWTCH-GO.version @@ -1 +1 @@ -2023-04-18-13-51-v0.0.3-16-ge12afc9 \ No newline at end of file +2023-04-20-15-37-v0.0.3-20-gb2a43b9 \ No newline at end of file diff --git a/lib/cwtch/cwtchNotifier.dart b/lib/cwtch/cwtchNotifier.dart index 85324657..e2c2b4db 100644 --- a/lib/cwtch/cwtchNotifier.dart +++ b/lib/cwtch/cwtchNotifier.dart @@ -379,8 +379,8 @@ class CwtchNotifier { }); profileCN.getProfile(data["ProfileOnion"])?.contactList.resort(); break; - case "NewRetValMessageFromPeer": - if (data["Path"] == "profile.name" && data["Exists"] == "true") { + case "UpdatedConversationAttribute": + if (data["Path"] == "profile.name") { if (data["Data"].toString().trim().length > 0) { // Update locally on the UI... if (profileCN.getProfile(data["ProfileOnion"])?.contactList.findContact(data["RemotePeer"]) != null) { @@ -388,37 +388,31 @@ class CwtchNotifier { } } } else if (data['Path'] == "profile.custom-profile-image") { - if (data["Exists"] == "true") { - EnvironmentConfig.debugLog("received ret val of custom profile image: $data"); - String fileKey = data['Data']; - var contact = profileCN.getProfile(data["ProfileOnion"])?.contactList.findContact(data["RemotePeer"]); - if (contact != null) { - profileCN.getProfile(data["ProfileOnion"])?.waitForDownloadComplete(contact.identifier, fileKey); - } + EnvironmentConfig.debugLog("received ret val of custom profile image: $data"); + String fileKey = data['Data']; + var contact = profileCN.getProfile(data["ProfileOnion"])?.contactList.findContact(data["RemotePeer"]); + if (contact != null) { + profileCN.getProfile(data["ProfileOnion"])?.waitForDownloadComplete(contact.identifier, fileKey); } } else if (data['Path'] == "profile.profile-attribute-1" || data['Path'] == "profile.profile-attribute-2" || data['Path'] == "profile.profile-attribute-3") { - if (data["Exists"] == "true") { - var contact = profileCN.getProfile(data["ProfileOnion"])?.contactList.findContact(data["RemotePeer"]); - if (contact != null) { - switch (data['Path']) { - case "profile.profile-attribute-1": - contact.setAttribute(0, data["Data"]); - break; - case "profile.profile-attribute-2": - contact.setAttribute(1, data["Data"]); - break; - case "profile.profile-attribute-3": - contact.setAttribute(2, data["Data"]); - break; - } + var contact = profileCN.getProfile(data["ProfileOnion"])?.contactList.findContact(data["RemotePeer"]); + if (contact != null) { + switch (data['Path']) { + case "profile.profile-attribute-1": + contact.setAttribute(0, data["Data"]); + break; + case "profile.profile-attribute-2": + contact.setAttribute(1, data["Data"]); + break; + case "profile.profile-attribute-3": + contact.setAttribute(2, data["Data"]); + break; } } } else if (data['Path'] == "profile.profile-status") { - if (data["Exists"] == "true") { - var contact = profileCN.getProfile(data["ProfileOnion"])?.contactList.findContact(data["RemotePeer"]); - if (contact != null) { - contact.setAvailabilityStatus(data['Data']); - } + var contact = profileCN.getProfile(data["ProfileOnion"])?.contactList.findContact(data["RemotePeer"]); + if (contact != null) { + contact.setAvailabilityStatus(data['Data']); } } else { EnvironmentConfig.debugLog("unhandled ret val event: ${data['Path']}"); diff --git a/lib/models/contact.dart b/lib/models/contact.dart index dec7bf4f..a12e19db 100644 --- a/lib/models/contact.dart +++ b/lib/models/contact.dart @@ -39,6 +39,7 @@ class ContactInfoState extends ChangeNotifier { final int identifier; final String onion; late String _nickname; + late String _localNickname; late ConversationNotificationPolicy _notificationPolicy; @@ -73,6 +74,7 @@ class ContactInfoState extends ChangeNotifier { this.identifier, this.onion, { nickname = "", + localNickname = "", isGroup = false, accepted = false, blocked = false, @@ -89,6 +91,7 @@ class ContactInfoState extends ChangeNotifier { pinned = false, }) { this._nickname = nickname; + this._localNickname = localNickname; this._isGroup = isGroup; this._accepted = accepted; this._blocked = blocked; @@ -107,7 +110,13 @@ class ContactInfoState extends ChangeNotifier { keys = Map>(); } - String get nickname => this._nickname; + String get nickname { + if (this._localNickname != "") { + return this._localNickname; + } + return this._nickname; + } + String get savePeerHistory => this._savePeerHistory; String? get acnCircuit => this._acnCircuit; @@ -146,6 +155,11 @@ class ContactInfoState extends ChangeNotifier { notifyListeners(); } + set localNickname(String newVal) { + this._localNickname = newVal; + notifyListeners(); + } + bool get isGroup => this._isGroup; set isGroup(bool newVal) { diff --git a/lib/models/filedownloadprogress.dart b/lib/models/filedownloadprogress.dart index 9212f379..52542206 100644 --- a/lib/models/filedownloadprogress.dart +++ b/lib/models/filedownloadprogress.dart @@ -8,12 +8,17 @@ class FileDownloadProgress { DateTime? timeStart; DateTime? timeEnd; DateTime? requested; + DateTime lastUpdate = DateTime.now(); FileDownloadProgress(this.chunksTotal, this.timeStart); double progress() { return 1.0 * chunksDownloaded / chunksTotal; } + + void markUpdate() { + lastUpdate = DateTime.now(); + } } String prettyBytes(int bytes) { diff --git a/lib/models/messages/filemessage.dart b/lib/models/messages/filemessage.dart index 53196dcd..d8ebc6cf 100644 --- a/lib/models/messages/filemessage.dart +++ b/lib/models/messages/filemessage.dart @@ -33,10 +33,8 @@ class FileMessage extends Message { int fileSize = shareObj['s'] as int; String fileKey = rootHash + "." + nonce; - if (metadata.attributes["file-downloaded"] != "true") { - if (!Provider.of(context, listen: false).downloadKnown(fileKey)) { - Provider.of(context, listen: false).cwtch.CheckDownloadStatus(Provider.of(context, listen: false).onion, fileKey); - } + if (!Provider.of(context, listen: false).downloadKnown(fileKey)) { + Provider.of(context, listen: false).cwtch.CheckDownloadStatus(Provider.of(context, listen: false).onion, fileKey); } if (!validHash(rootHash, nonce)) { diff --git a/lib/models/profile.dart b/lib/models/profile.dart index 0c43d519..86ef3f2b 100644 --- a/lib/models/profile.dart +++ b/lib/models/profile.dart @@ -67,6 +67,7 @@ class ProfileInfoState extends ChangeNotifier { this._unreadMessages += contact["numUnread"] as int; return ContactInfoState(this.onion, contact["identifier"], contact["onion"], nickname: contact["name"], + localNickname: contact["localname"], status: contact["status"], imagePath: contact["picture"], defaultImagePath: contact["isGroup"] ? contact["picture"] : contact["defaultPicture"], @@ -268,6 +269,7 @@ class ProfileInfoState extends ChangeNotifier { } this._downloads[fileKey]!.chunksDownloaded = progress; this._downloads[fileKey]!.chunksTotal = numChunks; + this._downloads[fileKey]!.markUpdate(); } notifyListeners(); } @@ -277,6 +279,7 @@ class ProfileInfoState extends ChangeNotifier { this._downloads[fileKey] = FileDownloadProgress(1, DateTime.now()); } this._downloads[fileKey]!.gotManifest = true; + this._downloads[fileKey]!.markUpdate(); notifyListeners(); } @@ -301,6 +304,7 @@ class ProfileInfoState extends ChangeNotifier { this._downloads[fileKey]!.timeEnd = DateTime.now(); this._downloads[fileKey]!.downloadedTo = finalPath; this._downloads[fileKey]!.complete = true; + this._downloads[fileKey]!.markUpdate(); notifyListeners(); } } @@ -333,9 +337,13 @@ class ProfileInfoState extends ChangeNotifier { this._downloads[fileKey]!.interrupted = true; return true; } + if (DateTime.now().difference(this._downloads[fileKey]!.lastUpdate) > Duration(minutes: 1)) { + this._downloads[fileKey]!.requested = null; + this._downloads[fileKey]!.interrupted = true; + return true; + } } } - return false; } @@ -343,6 +351,7 @@ class ProfileInfoState extends ChangeNotifier { if (this._downloads.containsKey(fileKey)) { this._downloads[fileKey]!.interrupted = false; this._downloads[fileKey]!.requested = DateTime.now(); + this._downloads[fileKey]!.markUpdate(); notifyListeners(); } } diff --git a/lib/views/peersettingsview.dart b/lib/views/peersettingsview.dart index 2688fa71..616609f7 100644 --- a/lib/views/peersettingsview.dart +++ b/lib/views/peersettingsview.dart @@ -146,7 +146,7 @@ class _PeerSettingsViewState extends State { onPressed: () { var profileOnion = Provider.of(context, listen: false).profileOnion; var conversation = Provider.of(context, listen: false).identifier; - Provider.of(context, listen: false).nickname = ctrlrNick.text; + Provider.of(context, listen: false).localNickname = ctrlrNick.text; Provider.of(context, listen: false).cwtch.SetConversationAttribute(profileOnion, conversation, "profile.name", ctrlrNick.text); final snackBar = SnackBar(content: Text(AppLocalizations.of(context)!.nickChangeSuccess)); ScaffoldMessenger.of(context).showSnackBar(snackBar); diff --git a/lib/widgets/filebubble.dart b/lib/widgets/filebubble.dart index 64d2bc78..7ab8282e 100644 --- a/lib/widgets/filebubble.dart +++ b/lib/widgets/filebubble.dart @@ -165,7 +165,7 @@ class FileBubbleState extends State { wdgDecorations = Text('\u202F'); } else if (downloadComplete && path != null) { // in this case, whatever marked download.complete would have also set the path - if (Provider.of(context).shouldPreview(path)) { + if (myFile != null && Provider.of(context).shouldPreview(path)) { isPreview = true; wdgDecorations = Center( widthFactor: 1.0, @@ -196,6 +196,7 @@ class FileBubbleState extends State { // so we probably have to request an info lookup if (!downloadInterrupted) { wdgDecorations = Text(AppLocalizations.of(context)!.fileCheckingStatus + '...' + '\u202F'); + // We should have already requested this... } else { var path = Provider.of(context).downloadFinalPath(widget.fileKey()) ?? ""; wdgDecorations = Visibility(