File Sharing Bug Fixes
continuous-integration/drone/pr Build is pending Details

- Allow restarting of file shares that have timed out
- Fix NPE in FileBubble caused by deleting the underlying file
- Upgrade Cwtch with more file sharing fixes
- Move from RetVal to UpdateConversationAttributes to minimze UI thread issues
- Update bindings
This commit is contained in:
Sarah Jamie Lewis 2023-04-20 15:48:00 -07:00
parent c2f0633efb
commit 133f4a9429
8 changed files with 58 additions and 37 deletions

View File

@ -1 +1 @@
2023-04-18-13-51-v0.0.3-16-ge12afc9 2023-04-20-15-37-v0.0.3-20-gb2a43b9

View File

@ -379,8 +379,8 @@ class CwtchNotifier {
}); });
profileCN.getProfile(data["ProfileOnion"])?.contactList.resort(); profileCN.getProfile(data["ProfileOnion"])?.contactList.resort();
break; break;
case "NewRetValMessageFromPeer": case "UpdatedConversationAttribute":
if (data["Path"] == "profile.name" && data["Exists"] == "true") { if (data["Path"] == "profile.name") {
if (data["Data"].toString().trim().length > 0) { if (data["Data"].toString().trim().length > 0) {
// Update locally on the UI... // Update locally on the UI...
if (profileCN.getProfile(data["ProfileOnion"])?.contactList.findContact(data["RemotePeer"]) != null) { if (profileCN.getProfile(data["ProfileOnion"])?.contactList.findContact(data["RemotePeer"]) != null) {
@ -388,37 +388,31 @@ class CwtchNotifier {
} }
} }
} else if (data['Path'] == "profile.custom-profile-image") { } else if (data['Path'] == "profile.custom-profile-image") {
if (data["Exists"] == "true") { EnvironmentConfig.debugLog("received ret val of custom profile image: $data");
EnvironmentConfig.debugLog("received ret val of custom profile image: $data"); String fileKey = data['Data'];
String fileKey = data['Data']; var contact = profileCN.getProfile(data["ProfileOnion"])?.contactList.findContact(data["RemotePeer"]);
var contact = profileCN.getProfile(data["ProfileOnion"])?.contactList.findContact(data["RemotePeer"]); if (contact != null) {
if (contact != null) { profileCN.getProfile(data["ProfileOnion"])?.waitForDownloadComplete(contact.identifier, fileKey);
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") { } 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"]);
var contact = profileCN.getProfile(data["ProfileOnion"])?.contactList.findContact(data["RemotePeer"]); if (contact != null) {
if (contact != null) { switch (data['Path']) {
switch (data['Path']) { case "profile.profile-attribute-1":
case "profile.profile-attribute-1": contact.setAttribute(0, data["Data"]);
contact.setAttribute(0, data["Data"]); break;
break; case "profile.profile-attribute-2":
case "profile.profile-attribute-2": contact.setAttribute(1, data["Data"]);
contact.setAttribute(1, data["Data"]); break;
break; case "profile.profile-attribute-3":
case "profile.profile-attribute-3": contact.setAttribute(2, data["Data"]);
contact.setAttribute(2, data["Data"]); break;
break;
}
} }
} }
} else if (data['Path'] == "profile.profile-status") { } else if (data['Path'] == "profile.profile-status") {
if (data["Exists"] == "true") { var contact = profileCN.getProfile(data["ProfileOnion"])?.contactList.findContact(data["RemotePeer"]);
var contact = profileCN.getProfile(data["ProfileOnion"])?.contactList.findContact(data["RemotePeer"]); if (contact != null) {
if (contact != null) { contact.setAvailabilityStatus(data['Data']);
contact.setAvailabilityStatus(data['Data']);
}
} }
} else { } else {
EnvironmentConfig.debugLog("unhandled ret val event: ${data['Path']}"); EnvironmentConfig.debugLog("unhandled ret val event: ${data['Path']}");

View File

@ -39,6 +39,7 @@ class ContactInfoState extends ChangeNotifier {
final int identifier; final int identifier;
final String onion; final String onion;
late String _nickname; late String _nickname;
late String _localNickname;
late ConversationNotificationPolicy _notificationPolicy; late ConversationNotificationPolicy _notificationPolicy;
@ -73,6 +74,7 @@ class ContactInfoState extends ChangeNotifier {
this.identifier, this.identifier,
this.onion, { this.onion, {
nickname = "", nickname = "",
localNickname = "",
isGroup = false, isGroup = false,
accepted = false, accepted = false,
blocked = false, blocked = false,
@ -89,6 +91,7 @@ class ContactInfoState extends ChangeNotifier {
pinned = false, pinned = false,
}) { }) {
this._nickname = nickname; this._nickname = nickname;
this._localNickname = localNickname;
this._isGroup = isGroup; this._isGroup = isGroup;
this._accepted = accepted; this._accepted = accepted;
this._blocked = blocked; this._blocked = blocked;
@ -107,7 +110,13 @@ class ContactInfoState extends ChangeNotifier {
keys = Map<String, GlobalKey<MessageRowState>>(); keys = Map<String, GlobalKey<MessageRowState>>();
} }
String get nickname => this._nickname; String get nickname {
if (this._localNickname != "") {
return this._localNickname;
}
return this._nickname;
}
String get savePeerHistory => this._savePeerHistory; String get savePeerHistory => this._savePeerHistory;
String? get acnCircuit => this._acnCircuit; String? get acnCircuit => this._acnCircuit;
@ -146,6 +155,11 @@ class ContactInfoState extends ChangeNotifier {
notifyListeners(); notifyListeners();
} }
set localNickname(String newVal) {
this._localNickname = newVal;
notifyListeners();
}
bool get isGroup => this._isGroup; bool get isGroup => this._isGroup;
set isGroup(bool newVal) { set isGroup(bool newVal) {

View File

@ -8,12 +8,17 @@ class FileDownloadProgress {
DateTime? timeStart; DateTime? timeStart;
DateTime? timeEnd; DateTime? timeEnd;
DateTime? requested; DateTime? requested;
DateTime lastUpdate = DateTime.now();
FileDownloadProgress(this.chunksTotal, this.timeStart); FileDownloadProgress(this.chunksTotal, this.timeStart);
double progress() { double progress() {
return 1.0 * chunksDownloaded / chunksTotal; return 1.0 * chunksDownloaded / chunksTotal;
} }
void markUpdate() {
lastUpdate = DateTime.now();
}
} }
String prettyBytes(int bytes) { String prettyBytes(int bytes) {

View File

@ -33,10 +33,8 @@ class FileMessage extends Message {
int fileSize = shareObj['s'] as int; int fileSize = shareObj['s'] as int;
String fileKey = rootHash + "." + nonce; String fileKey = rootHash + "." + nonce;
if (metadata.attributes["file-downloaded"] != "true") { if (!Provider.of<ProfileInfoState>(context, listen: false).downloadKnown(fileKey)) {
if (!Provider.of<ProfileInfoState>(context, listen: false).downloadKnown(fileKey)) { Provider.of<FlwtchState>(context, listen: false).cwtch.CheckDownloadStatus(Provider.of<ProfileInfoState>(context, listen: false).onion, fileKey);
Provider.of<FlwtchState>(context, listen: false).cwtch.CheckDownloadStatus(Provider.of<ProfileInfoState>(context, listen: false).onion, fileKey);
}
} }
if (!validHash(rootHash, nonce)) { if (!validHash(rootHash, nonce)) {

View File

@ -67,6 +67,7 @@ class ProfileInfoState extends ChangeNotifier {
this._unreadMessages += contact["numUnread"] as int; this._unreadMessages += contact["numUnread"] as int;
return ContactInfoState(this.onion, contact["identifier"], contact["onion"], return ContactInfoState(this.onion, contact["identifier"], contact["onion"],
nickname: contact["name"], nickname: contact["name"],
localNickname: contact["localname"],
status: contact["status"], status: contact["status"],
imagePath: contact["picture"], imagePath: contact["picture"],
defaultImagePath: contact["isGroup"] ? contact["picture"] : contact["defaultPicture"], defaultImagePath: contact["isGroup"] ? contact["picture"] : contact["defaultPicture"],
@ -268,6 +269,7 @@ class ProfileInfoState extends ChangeNotifier {
} }
this._downloads[fileKey]!.chunksDownloaded = progress; this._downloads[fileKey]!.chunksDownloaded = progress;
this._downloads[fileKey]!.chunksTotal = numChunks; this._downloads[fileKey]!.chunksTotal = numChunks;
this._downloads[fileKey]!.markUpdate();
} }
notifyListeners(); notifyListeners();
} }
@ -277,6 +279,7 @@ class ProfileInfoState extends ChangeNotifier {
this._downloads[fileKey] = FileDownloadProgress(1, DateTime.now()); this._downloads[fileKey] = FileDownloadProgress(1, DateTime.now());
} }
this._downloads[fileKey]!.gotManifest = true; this._downloads[fileKey]!.gotManifest = true;
this._downloads[fileKey]!.markUpdate();
notifyListeners(); notifyListeners();
} }
@ -301,6 +304,7 @@ class ProfileInfoState extends ChangeNotifier {
this._downloads[fileKey]!.timeEnd = DateTime.now(); this._downloads[fileKey]!.timeEnd = DateTime.now();
this._downloads[fileKey]!.downloadedTo = finalPath; this._downloads[fileKey]!.downloadedTo = finalPath;
this._downloads[fileKey]!.complete = true; this._downloads[fileKey]!.complete = true;
this._downloads[fileKey]!.markUpdate();
notifyListeners(); notifyListeners();
} }
} }
@ -333,9 +337,13 @@ class ProfileInfoState extends ChangeNotifier {
this._downloads[fileKey]!.interrupted = true; this._downloads[fileKey]!.interrupted = true;
return 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; return false;
} }
@ -343,6 +351,7 @@ class ProfileInfoState extends ChangeNotifier {
if (this._downloads.containsKey(fileKey)) { if (this._downloads.containsKey(fileKey)) {
this._downloads[fileKey]!.interrupted = false; this._downloads[fileKey]!.interrupted = false;
this._downloads[fileKey]!.requested = DateTime.now(); this._downloads[fileKey]!.requested = DateTime.now();
this._downloads[fileKey]!.markUpdate();
notifyListeners(); notifyListeners();
} }
} }

View File

@ -146,7 +146,7 @@ class _PeerSettingsViewState extends State<PeerSettingsView> {
onPressed: () { onPressed: () {
var profileOnion = Provider.of<ContactInfoState>(context, listen: false).profileOnion; var profileOnion = Provider.of<ContactInfoState>(context, listen: false).profileOnion;
var conversation = Provider.of<ContactInfoState>(context, listen: false).identifier; var conversation = Provider.of<ContactInfoState>(context, listen: false).identifier;
Provider.of<ContactInfoState>(context, listen: false).nickname = ctrlrNick.text; Provider.of<ContactInfoState>(context, listen: false).localNickname = ctrlrNick.text;
Provider.of<FlwtchState>(context, listen: false).cwtch.SetConversationAttribute(profileOnion, conversation, "profile.name", ctrlrNick.text); Provider.of<FlwtchState>(context, listen: false).cwtch.SetConversationAttribute(profileOnion, conversation, "profile.name", ctrlrNick.text);
final snackBar = SnackBar(content: Text(AppLocalizations.of(context)!.nickChangeSuccess)); final snackBar = SnackBar(content: Text(AppLocalizations.of(context)!.nickChangeSuccess));
ScaffoldMessenger.of(context).showSnackBar(snackBar); ScaffoldMessenger.of(context).showSnackBar(snackBar);

View File

@ -165,7 +165,7 @@ class FileBubbleState extends State<FileBubble> {
wdgDecorations = Text('\u202F'); wdgDecorations = Text('\u202F');
} else if (downloadComplete && path != null) { } else if (downloadComplete && path != null) {
// in this case, whatever marked download.complete would have also set the path // in this case, whatever marked download.complete would have also set the path
if (Provider.of<Settings>(context).shouldPreview(path)) { if (myFile != null && Provider.of<Settings>(context).shouldPreview(path)) {
isPreview = true; isPreview = true;
wdgDecorations = Center( wdgDecorations = Center(
widthFactor: 1.0, widthFactor: 1.0,
@ -196,6 +196,7 @@ class FileBubbleState extends State<FileBubble> {
// so we probably have to request an info lookup // so we probably have to request an info lookup
if (!downloadInterrupted) { if (!downloadInterrupted) {
wdgDecorations = Text(AppLocalizations.of(context)!.fileCheckingStatus + '...' + '\u202F'); wdgDecorations = Text(AppLocalizations.of(context)!.fileCheckingStatus + '...' + '\u202F');
// We should have already requested this...
} else { } else {
var path = Provider.of<ProfileInfoState>(context).downloadFinalPath(widget.fileKey()) ?? ""; var path = Provider.of<ProfileInfoState>(context).downloadFinalPath(widget.fileKey()) ?? "";
wdgDecorations = Visibility( wdgDecorations = Visibility(