mirror of
https://github.com/twonlyapp/twonly-app.git
synced 2026-01-15 09:28:41 +00:00
some performance improvements and fix #18
This commit is contained in:
parent
504b528770
commit
e21935eedf
8 changed files with 66 additions and 34 deletions
|
|
@ -27,7 +27,7 @@ bool globalIsAppInBackground = true;
|
|||
|
||||
// these two callbacks are called on updated to the corresponding database
|
||||
Function globalCallBackOnContactChange = () {};
|
||||
Future Function(int) globalCallBackOnMessageChange = (a) async {};
|
||||
Future Function(int, int?) globalCallBackOnMessageChange = (a, b) async {};
|
||||
Function(List<int>, bool) globalCallBackOnDownloadChange = (a, b) {};
|
||||
|
||||
/// The Widget that configures your application.
|
||||
|
|
@ -67,8 +67,10 @@ class _MyAppState extends State<MyApp> with WidgetsBindingObserver {
|
|||
context.read<DownloadChangeProvider>().update(token, add);
|
||||
};
|
||||
|
||||
globalCallBackOnMessageChange = (userId) async {
|
||||
await context.read<MessagesChangeProvider>().updateLastMessageFor(userId);
|
||||
globalCallBackOnMessageChange = (userId, messageId) async {
|
||||
await context
|
||||
.read<MessagesChangeProvider>()
|
||||
.updateLastMessageFor(userId, messageId);
|
||||
};
|
||||
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
|
|
@ -194,7 +196,7 @@ class _MyAppState extends State<MyApp> with WidgetsBindingObserver {
|
|||
globalCallbackConnectionState = (a) {};
|
||||
globalCallBackOnDownloadChange = (a, b) {};
|
||||
globalCallBackOnContactChange = () {};
|
||||
globalCallBackOnMessageChange = (a) async {};
|
||||
globalCallBackOnMessageChange = (a, b) async {};
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -152,7 +152,7 @@ class DbMessages extends CvModelBase {
|
|||
);
|
||||
int? fromUserId = await getFromUserIdByMessageId(messageId);
|
||||
if (fromUserId != null) {
|
||||
globalCallBackOnMessageChange(fromUserId);
|
||||
globalCallBackOnMessageChange(fromUserId, messageId);
|
||||
}
|
||||
return fromUserId;
|
||||
}
|
||||
|
|
@ -179,7 +179,7 @@ class DbMessages extends CvModelBase {
|
|||
columnOtherUserId: userIdFrom,
|
||||
columnSendAt: messageSendAt.toIso8601String()
|
||||
});
|
||||
globalCallBackOnMessageChange(userIdFrom);
|
||||
globalCallBackOnMessageChange(userIdFrom, messageId);
|
||||
return messageId;
|
||||
} catch (e) {
|
||||
Logger("messsage_model/insertMyMessage").shout("$e");
|
||||
|
|
@ -200,7 +200,7 @@ class DbMessages extends CvModelBase {
|
|||
columnOtherUserId: userIdFrom,
|
||||
columnSendAt: messageSendAt.toIso8601String()
|
||||
});
|
||||
globalCallBackOnMessageChange(userIdFrom);
|
||||
globalCallBackOnMessageChange(userIdFrom, messageId);
|
||||
return messageId;
|
||||
} catch (e) {
|
||||
Logger("messsage_model/insertOtherMessage").shout("$e");
|
||||
|
|
@ -235,6 +235,13 @@ class DbMessages extends CvModelBase {
|
|||
return messages;
|
||||
}
|
||||
|
||||
static Future<DbMessage?> getMessageById(int messageId) async {
|
||||
var rows = await dbProvider.db!.query(tableName,
|
||||
where: "$columnMessageId = ?", whereArgs: [messageId]);
|
||||
List<DbMessage> messages = await convertToDbMessage(rows);
|
||||
return messages.firstOrNull;
|
||||
}
|
||||
|
||||
static Future<List<DbMessage>> getAllMessagesForRetransmitting() async {
|
||||
var rows = await dbProvider.db!.query(
|
||||
tableName,
|
||||
|
|
@ -289,7 +296,7 @@ class DbMessages extends CvModelBase {
|
|||
if (notifyFlutterState) {
|
||||
int? fromUserId = await getFromUserIdByMessageId(messageId);
|
||||
if (fromUserId != null) {
|
||||
globalCallBackOnMessageChange(fromUserId);
|
||||
globalCallBackOnMessageChange(fromUserId, messageId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -302,7 +309,7 @@ class DbMessages extends CvModelBase {
|
|||
where: "$columnMessageOtherId = ?",
|
||||
whereArgs: [messageId],
|
||||
);
|
||||
globalCallBackOnMessageChange(fromUserId);
|
||||
globalCallBackOnMessageChange(fromUserId, messageId);
|
||||
}
|
||||
|
||||
// this ensures that the message id can be spoofed by another person
|
||||
|
|
@ -314,7 +321,7 @@ class DbMessages extends CvModelBase {
|
|||
where: "$columnMessageId = ? AND $columnOtherUserId = ?",
|
||||
whereArgs: [messageId, fromUserId],
|
||||
);
|
||||
globalCallBackOnMessageChange(fromUserId);
|
||||
globalCallBackOnMessageChange(fromUserId, messageId);
|
||||
}
|
||||
|
||||
static Future userOpenedOtherMessage(
|
||||
|
|
@ -351,7 +358,7 @@ class DbMessages extends CvModelBase {
|
|||
where: "$messageId = ? AND $columnOtherUserId = ?",
|
||||
whereArgs: [messageId, fromUserId],
|
||||
);
|
||||
globalCallBackOnMessageChange(fromUserId);
|
||||
globalCallBackOnMessageChange(fromUserId, messageId);
|
||||
}
|
||||
|
||||
@override
|
||||
|
|
@ -374,6 +381,7 @@ class DbMessages extends CvModelBase {
|
|||
List<dynamic> fromDb) async {
|
||||
try {
|
||||
List<DbMessage> parsedUsers = [];
|
||||
final box = await getMediaStorage();
|
||||
for (int i = 0; i < fromDb.length; i++) {
|
||||
dynamic messageOpenedAt = fromDb[i][columnMessageOpenedAt];
|
||||
|
||||
|
|
@ -397,7 +405,8 @@ class DbMessages extends CvModelBase {
|
|||
if (messageOtherId != null) {
|
||||
if (content is MediaMessageContent) {
|
||||
// when the media was send from the user itself the content is null
|
||||
isDownloaded = await isMediaDownloaded(content.downloadToken);
|
||||
isDownloaded =
|
||||
box.containsKey("${content.downloadToken}_downloaded");
|
||||
}
|
||||
}
|
||||
parsedUsers.add(
|
||||
|
|
|
|||
|
|
@ -91,7 +91,11 @@ Future sendTextMessage(Int64 target, String message) async {
|
|||
DateTime messageSendAt = DateTime.now();
|
||||
|
||||
int? messageId = await DbMessages.insertMyMessage(
|
||||
target.toInt(), MessageKind.textMessage, content, messageSendAt);
|
||||
target.toInt(),
|
||||
MessageKind.textMessage,
|
||||
content,
|
||||
messageSendAt,
|
||||
);
|
||||
if (messageId == null) return;
|
||||
|
||||
Message msg = Message(
|
||||
|
|
@ -264,13 +268,11 @@ Future sendImage(
|
|||
}
|
||||
|
||||
// first step encrypt and store the encrypted image
|
||||
for (SendImage task in tasks) {
|
||||
await task.encryptAndStore();
|
||||
}
|
||||
await Future.wait(tasks.map((task) => task.encryptAndStore()));
|
||||
|
||||
// after the images are safely stored try do upload them one by one
|
||||
for (SendImage task in tasks) {
|
||||
await task.upload();
|
||||
task.upload();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -332,11 +334,6 @@ Future<Uint8List?> getDownloadedMedia(
|
|||
return media;
|
||||
}
|
||||
|
||||
Future<bool> isMediaDownloaded(List<int> mediaToken) async {
|
||||
final box = await getMediaStorage();
|
||||
return box.containsKey("${mediaToken}_downloaded");
|
||||
}
|
||||
|
||||
Future initMediaStorage() async {
|
||||
final storage = getSecureStorage();
|
||||
var containsEncryptionKey =
|
||||
|
|
|
|||
|
|
@ -57,15 +57,15 @@ Future<client.Response> handleDownloadData(DownloadData data) async {
|
|||
final box = await getMediaStorage();
|
||||
|
||||
String boxId = data.uploadToken.toString();
|
||||
int? messageId = box.get("${data.uploadToken}_messageId");
|
||||
if (data.fin && data.data.isEmpty) {
|
||||
// media file was deleted by the server. remove the media from device
|
||||
|
||||
int? messageId = box.get("${data.uploadToken}_messageId");
|
||||
if (messageId != null) {
|
||||
int? fromUserId = await DbMessages.deleteMessageById(messageId);
|
||||
box.delete(boxId);
|
||||
if (fromUserId != null) {
|
||||
globalCallBackOnMessageChange(fromUserId);
|
||||
globalCallBackOnMessageChange(fromUserId, messageId);
|
||||
}
|
||||
box.delete("${data.uploadToken}_fromUserId");
|
||||
box.delete("${data.uploadToken}_downloaded");
|
||||
|
|
@ -107,7 +107,7 @@ Future<client.Response> handleDownloadData(DownloadData data) async {
|
|||
}
|
||||
|
||||
box.delete(boxId);
|
||||
await globalCallBackOnMessageChange(fromUserId);
|
||||
await globalCallBackOnMessageChange(fromUserId, messageId);
|
||||
globalCallBackOnDownloadChange(data.uploadToken, false);
|
||||
}
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -17,16 +17,31 @@ class MessagesChangeProvider with ChangeNotifier, DiagnosticableTreeMixin {
|
|||
Map<int, int> get changeCounter => _changeCounter;
|
||||
Map<int, int> get flamesCounter => _flamesCounter;
|
||||
|
||||
Future updateLastMessageFor(int targetUserId) async {
|
||||
Future updateLastMessageFor(int targetUserId, int? messageId) async {
|
||||
DbMessage? last =
|
||||
await DbMessages.getLastMessagesForPreviewForUser(targetUserId);
|
||||
if (last != null) {
|
||||
_lastMessage[last.otherUserId] = last;
|
||||
}
|
||||
flamesCounter[targetUserId] = await getFlamesForOtherUser(targetUserId);
|
||||
notifyListeners();
|
||||
// notifyListeners();
|
||||
|
||||
loadMessagesForUser(targetUserId, force: true);
|
||||
if (messageId == null || _allMessagesFromUser[targetUserId] == null) {
|
||||
loadMessagesForUser(targetUserId, force: true);
|
||||
} else {
|
||||
DbMessage? msg = await DbMessages.getMessageById(messageId);
|
||||
if (msg != null) {
|
||||
int index = _allMessagesFromUser[targetUserId]!
|
||||
.indexWhere((x) => x.messageId == messageId);
|
||||
if (index == -1) {
|
||||
_allMessagesFromUser[targetUserId]!.insert(0, msg);
|
||||
} else {
|
||||
_allMessagesFromUser[targetUserId]![index] = msg;
|
||||
}
|
||||
}
|
||||
_allMessagesFromUser[targetUserId] = allMessagesFromUser[targetUserId]!;
|
||||
notifyListeners();
|
||||
}
|
||||
}
|
||||
|
||||
Future loadMessagesForUser(int targetUserId, {bool force = false}) async {
|
||||
|
|
|
|||
|
|
@ -373,15 +373,16 @@ class _ShareImageEditorView extends State<ShareImageEditorView> {
|
|||
icon: FaIcon(FontAwesomeIcons.solidPaperPlane),
|
||||
onPressed: () async {
|
||||
if (sendNextMediaToUserId != null) {
|
||||
Navigator.popUntil(context, (route) => route.isFirst);
|
||||
Uint8List? imageBytes = await getMergedImage();
|
||||
globalUpdateOfHomeViewPageIndex(1);
|
||||
sendImage(
|
||||
[Int64(sendNextMediaToUserId)],
|
||||
imageBytes!,
|
||||
_isRealTwonly,
|
||||
_maxShowTime,
|
||||
);
|
||||
Navigator.popUntil(context, (route) => route.isFirst);
|
||||
globalUpdateOfHomeViewPageIndex(1);
|
||||
|
||||
// send hier...
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@ class _ShareImageView extends State<ShareImageView> {
|
|||
List<Contact> _bestFriends = [];
|
||||
int maxTotalMediaCounter = 0;
|
||||
Uint8List? imageBytes;
|
||||
bool sendingImage = false;
|
||||
final HashSet<Int64> _selectedUserIds = HashSet<Int64>();
|
||||
final TextEditingController searchUserName = TextEditingController();
|
||||
bool showRealTwonlyWarning = false;
|
||||
|
|
@ -188,7 +189,7 @@ class _ShareImageView extends State<ShareImageView> {
|
|||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
children: [
|
||||
FilledButton.icon(
|
||||
icon: imageBytes == null
|
||||
icon: imageBytes == null || sendingImage
|
||||
? SizedBox(
|
||||
height: 12,
|
||||
width: 12,
|
||||
|
|
@ -202,14 +203,19 @@ class _ShareImageView extends State<ShareImageView> {
|
|||
if (imageBytes == null || _selectedUserIds.isEmpty) {
|
||||
return;
|
||||
}
|
||||
sendImage(
|
||||
setState(() {
|
||||
sendingImage = true;
|
||||
});
|
||||
await sendImage(
|
||||
_selectedUserIds.toList(),
|
||||
imageBytes!,
|
||||
widget.isRealTwonly,
|
||||
widget.maxShowTime,
|
||||
);
|
||||
Navigator.popUntil(context, (route) => route.isFirst);
|
||||
globalUpdateOfHomeViewPageIndex(1);
|
||||
if (context.mounted) {
|
||||
Navigator.popUntil(context, (route) => route.isFirst);
|
||||
globalUpdateOfHomeViewPageIndex(1);
|
||||
}
|
||||
},
|
||||
style: ButtonStyle(
|
||||
padding: WidgetStateProperty.all<EdgeInsets>(
|
||||
|
|
|
|||
|
|
@ -165,6 +165,7 @@ class _ChatItemDetailsViewState extends State<ChatItemDetailsView> {
|
|||
.watch<MessagesChangeProvider>()
|
||||
.allMessagesFromUser[user.userId.toInt()] ??
|
||||
[];
|
||||
print(messages.length);
|
||||
|
||||
messages.where((x) => x.messageOpenedAt == null).forEach((message) {
|
||||
if (message.messageOtherId != null &&
|
||||
|
|
@ -219,6 +220,7 @@ class _ChatItemDetailsViewState extends State<ChatItemDetailsView> {
|
|||
itemCount: messages.length, // Number of items in the list
|
||||
reverse: true,
|
||||
itemBuilder: (context, i) {
|
||||
print(i);
|
||||
bool lastMessageFromSameUser = false;
|
||||
if (i > 0) {
|
||||
lastMessageFromSameUser =
|
||||
|
|
|
|||
Loading…
Reference in a new issue