Merge pull request 'calculate server progress based on last message, nowtime, and message flow; display progress on group contact and remote server' (#340) from serverProgress into trunk
continuous-integration/drone/push Build is passing Details

Reviewed-on: #340
Reviewed-by: Sarah Jamie Lewis <sarah@openprivacy.ca>
This commit is contained in:
Dan Ballard 2022-02-02 18:05:49 +00:00
commit ca03ddbc53
12 changed files with 93 additions and 33 deletions

View File

@ -5,6 +5,7 @@ import 'package:cwtch/models/contact.dart';
import 'package:cwtch/models/message.dart';
import 'package:cwtch/models/profilelist.dart';
import 'package:cwtch/models/profileservers.dart';
import 'package:cwtch/models/remoteserver.dart';
import 'package:cwtch/models/servers.dart';
import 'package:cwtch/notification_manager.dart';
import 'package:provider/provider.dart';
@ -193,7 +194,8 @@ class CwtchNotifier {
var senderHandle = data['RemotePeer'];
var senderImage = data['Picture'];
var timestampSent = DateTime.tryParse(data['TimestampSent'])!;
var currentTotal = profileCN.getProfile(data["ProfileOnion"])?.contactList.getContact(identifier)!.totalMessages;
var contact = profileCN.getProfile(data["ProfileOnion"])?.contactList.getContact(identifier);
var currentTotal = contact!.totalMessages;
var isAuto = data['Auto'] == "true";
String? contenthash = data['ContentHash'];
var selectedConversation = appState.selectedProfile == data["ProfileOnion"] && appState.selectedConversation == identifier;
@ -214,6 +216,8 @@ class CwtchNotifier {
notificationManager.notify("New Message From Group!");
}
RemoteServerInfoState? server = profileCN.getProfile(data["ProfileOnion"])?.serverList.getServer(contact.server);
server?.updateSyncProgressFor(timestampSent);
} else {
// This is dealt with by IndexedAcknowledgment
EnvironmentConfig.debugLog("new message from group from yourself - this should not happen");

View File

@ -211,6 +211,7 @@ class ContactInfoState extends ChangeNotifier {
newMarker++;
}
this._lastMessageTime = timestamp;
this.messageCache.addNew(profileOnion, identifier, messageID, timestamp, senderHandle, senderImage, isAuto, data, contenthash);
this.totalMessages += 1;

View File

@ -1,5 +1,6 @@
import 'dart:convert';
import 'package:cwtch/models/remoteserver.dart';
import 'package:flutter/widgets.dart';
import 'contact.dart';
@ -72,7 +73,7 @@ class ProfileInfoState extends ChangeNotifier {
List<dynamic> servers = jsonDecode(serversJson);
this._servers.replace(servers.map((server) {
// TODO Keys...
return RemoteServerInfoState(onion: server["onion"], identifier: server["identifier"], description: server["description"], status: server["status"]);
return RemoteServerInfoState(server["onion"], server["identifier"], server["description"], server["status"]);
}));
this._contacts.contacts.forEach((contact) {

View File

@ -1,3 +1,4 @@
import 'package:cwtch/models/remoteserver.dart';
import 'package:flutter/material.dart';
import 'contact.dart';
@ -33,12 +34,17 @@ class ProfileServerListState extends ChangeNotifier {
// return -1 = a first in list
// return 1 = b first in list
// online v offline
// online v syncing v offline
if (a.status == "Synced" && b.status != "Synced") {
return -1;
} else if (a.status != "Synced" && b.status == "Synced") {
return 1;
}
if (a.status == "Authenticated" && b.status != "Authenticated") {
return -1;
} else if (a.status != "Authenticated" && b.status == "Authenticated") {
return 1;
}
// num of groups
if (a.groups.length > b.groups.length) {
@ -65,30 +71,3 @@ class ProfileServerListState extends ChangeNotifier {
List<RemoteServerInfoState> get servers => _servers.sublist(0); //todo: copy?? dont want caller able to bypass changenotifier
}
class RemoteServerInfoState extends ChangeNotifier {
final String onion;
final int identifier;
String status;
String description;
List<ContactInfoState> _groups = [];
RemoteServerInfoState({required this.onion, required this.identifier, required this.description, required this.status});
void updateDescription(String newDescription) {
this.description = newDescription;
notifyListeners();
}
void clearGroups() {
_groups = [];
}
void addGroup(ContactInfoState group) {
_groups.add(group);
notifyListeners();
}
List<ContactInfoState> get groups => _groups.sublist(0); //todo: copy?? dont want caller able to bypass changenotifier
}

View File

@ -0,0 +1,55 @@
import 'package:flutter/cupertino.dart';
import 'contact.dart';
class RemoteServerInfoState extends ChangeNotifier {
final String onion;
final int identifier;
String _status;
String description;
List<ContactInfoState> _groups = [];
double syncProgress = 0;
DateTime lastPreSyncMessagTime = new DateTime(2020);
RemoteServerInfoState(this.onion, this.identifier, this.description, this._status);
void updateDescription(String newDescription) {
this.description = newDescription;
notifyListeners();
}
void clearGroups() {
_groups = [];
}
void addGroup(ContactInfoState group) {
_groups.add(group);
notifyListeners();
}
String get status => _status;
set status(String newStatus) {
_status = newStatus;
if (status == "Authenticated") {
// syncing, set lastPreSyncMessageTime
_groups.forEach((g) {
if(g.lastMessageTime.isAfter(lastPreSyncMessagTime)) {
lastPreSyncMessagTime = g.lastMessageTime;
}
});
}
notifyListeners();
}
// updateSyncProgressFor point takes a message's time, and updates the server sync progress,
// based on that point in time between the precalculated lastPreSyncMessagTime and Now
void updateSyncProgressFor(DateTime point) {
var range = lastPreSyncMessagTime.difference(DateTime.now());
var pointFromStart = lastPreSyncMessagTime.difference(point);
syncProgress = pointFromStart.inSeconds / range.inSeconds;
notifyListeners();
}
List<ContactInfoState> get groups => _groups.sublist(0); //todo: copy?? dont want caller able to bypass changenotifier
}

View File

@ -2,6 +2,7 @@ import 'dart:convert';
import 'package:cwtch/cwtch_icons_icons.dart';
import 'package:cwtch/models/profile.dart';
import 'package:cwtch/models/remoteserver.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:cwtch/errorHandler.dart';

View File

@ -3,6 +3,7 @@ import 'package:cwtch/models/appstate.dart';
import 'package:cwtch/models/contact.dart';
import 'package:cwtch/models/contactlist.dart';
import 'package:cwtch/models/profile.dart';
import 'package:cwtch/models/profilelist.dart';
import 'package:cwtch/views/profileserversview.dart';
import 'package:flutter/material.dart';
import 'package:cwtch/widgets/contactrow.dart';
@ -154,8 +155,15 @@ class _ContactsViewState extends State<ContactsView> {
Widget _buildContactList() {
final tiles = Provider.of<ContactListState>(context).filteredList().map((ContactInfoState contact) {
return ChangeNotifierProvider<ContactInfoState>.value(key: ValueKey(contact.profileOnion + "" + contact.onion), value: contact, builder: (_, __) => RepaintBoundary(child: ContactRow()));
return MultiProvider(
providers: [
ChangeNotifierProvider.value(value: contact),
ChangeNotifierProvider.value(value: Provider.of<ProfileInfoState>(context).serverList),
],
builder: (context, child) => RepaintBoundary(child: ContactRow()),
);
});
final divided = ListTile.divideTiles(
context: context,
tiles: tiles,

View File

@ -1,5 +1,6 @@
import 'package:cwtch/models/profile.dart';
import 'package:cwtch/models/profileservers.dart';
import 'package:cwtch/models/remoteserver.dart';
import 'package:cwtch/models/servers.dart';
import 'package:cwtch/widgets/remoteserverrow.dart';
import 'package:flutter/material.dart';

View File

@ -4,6 +4,7 @@ import 'package:cwtch/cwtch_icons_icons.dart';
import 'package:cwtch/models/contact.dart';
import 'package:cwtch/models/profile.dart';
import 'package:cwtch/models/profileservers.dart';
import 'package:cwtch/models/remoteserver.dart';
import 'package:cwtch/models/servers.dart';
import 'package:cwtch/widgets/buttontextfield.dart';
import 'package:cwtch/widgets/contactrow.dart';

View File

@ -3,6 +3,7 @@ import 'dart:io';
import 'package:cwtch/models/appstate.dart';
import 'package:cwtch/models/contact.dart';
import 'package:cwtch/models/profile.dart';
import 'package:cwtch/models/profileservers.dart';
import 'package:cwtch/views/contactsview.dart';
import 'package:flutter/material.dart';
import 'package:flutter/painting.dart';
@ -66,6 +67,7 @@ class _ContactRowState extends State<ContactRow> {
visible: contact.isGroup && contact.status == "Authenticated",
child: LinearProgressIndicator(
color: Provider.of<Settings>(context).theme.defaultButtonActiveColor,
value: Provider.of<ProfileInfoState>(context).serverList.getServer(contact.server)?.syncProgress,
)),
Visibility(
visible: !Provider.of<Settings>(context).streamerMode,

View File

@ -91,7 +91,7 @@ class _ProfileRowState extends State<ProfileRow> {
return MultiProvider(
providers: [
ChangeNotifierProvider<ProfileInfoState>.value(value: profile),
ChangeNotifierProvider<ContactListState>.value(value: profile.contactList),
ChangeNotifierProvider<ContactListState>.value(value: profile.contactList)
],
builder: (innercontext, widget) {
var appState = Provider.of<AppState>(context);

View File

@ -1,6 +1,7 @@
import 'package:cwtch/main.dart';
import 'package:cwtch/models/profile.dart';
import 'package:cwtch/models/profileservers.dart';
import 'package:cwtch/models/remoteserver.dart';
import 'package:cwtch/models/servers.dart';
import 'package:cwtch/views/addeditservers.dart';
import 'package:cwtch/views/remoteserverview.dart';
@ -55,7 +56,13 @@ class _RemoteServerRowState extends State<RemoteServerRow> {
softWrap: true,
overflow: TextOverflow.ellipsis,
style: TextStyle(color: running ? Provider.of<Settings>(context).theme.portraitOnlineBorderColor : Provider.of<Settings>(context).theme.portraitOfflineBorderColor),
)))
))),
Visibility(
visible: server.status == "Authenticated",
child: LinearProgressIndicator(
color: Provider.of<Settings>(context).theme.defaultButtonActiveColor,
value: server.syncProgress,
)),
],
)),
]),