This commit is contained in:
otsmr 2025-02-10 23:28:36 +01:00
parent ea7b29f594
commit a121aa6f23
3 changed files with 55 additions and 68 deletions

View file

@ -158,12 +158,12 @@ class _MyAppState extends State<MyApp> with WidgetsBindingObserver {
}
Future _stopService() async {
FlutterForegroundTask.sendDataToTask("");
await FlutterForegroundTask.stopService();
if (context.mounted) {
context.read<MessagesChangeProvider>().init();
context.read<MessagesChangeProvider>().init(afterPaused: true);
context.read<ContactChangeProvider>().update();
}
FlutterForegroundTask.sendDataToTask("");
await FlutterForegroundTask.stopService();
if (!apiProvider.isAuthenticated) {
apiProvider.connect();
}

View file

@ -7,10 +7,13 @@ import 'package:twonly/src/utils/misc.dart';
/// for every contact.
class MessagesChangeProvider with ChangeNotifier, DiagnosticableTreeMixin {
final Map<int, DbMessage> _lastMessage = <int, DbMessage>{};
final Map<int, List<DbMessage>> _allMessagesFromUser =
<int, List<DbMessage>>{};
final Map<int, int> _changeCounter = <int, int>{};
final Map<int, int> _flamesCounter = <int, int>{};
Map<int, DbMessage> get lastMessage => _lastMessage;
Map<int, List<DbMessage>> get allMessagesFromUser => _allMessagesFromUser;
Map<int, int> get changeCounter => _changeCounter;
Map<int, int> get flamesCounter => _flamesCounter;
@ -20,15 +23,20 @@ class MessagesChangeProvider with ChangeNotifier, DiagnosticableTreeMixin {
if (last != null) {
_lastMessage[last.otherUserId] = last;
}
if (!changeCounter.containsKey(targetUserId)) {
changeCounter[targetUserId] = 0;
}
changeCounter[targetUserId] = changeCounter[targetUserId]! + 1;
flamesCounter[targetUserId] = await getFlamesForOtherUser(targetUserId);
notifyListeners();
loadMessagesForUser(targetUserId, force: true);
}
Future loadMessagesForUser(int targetUserId, {bool force = false}) async {
if (!force && _allMessagesFromUser[targetUserId] != null) return;
_allMessagesFromUser[targetUserId] =
await DbMessages.getAllMessagesForUser(targetUserId);
notifyListeners();
}
void init() async {
void init({bool afterPaused = false}) async {
// load everything from the database
List<Contact> allContacts = await DbContacts.getUsers();
for (Contact contact in allContacts) {
@ -41,5 +49,10 @@ class MessagesChangeProvider with ChangeNotifier, DiagnosticableTreeMixin {
await getFlamesForOtherUser(contact.userId.toInt());
}
notifyListeners();
if (afterPaused) {
for (int targetUserId in _allMessagesFromUser.keys) {
loadMessagesForUser(targetUserId, force: true);
}
}
}
}

View file

@ -129,64 +129,25 @@ class ChatItemDetailsView extends StatefulWidget {
}
class _ChatItemDetailsViewState extends State<ChatItemDetailsView> {
List<DbMessage> _messages = [];
int lastChangeCounter = 0;
final TextEditingController newMessageController = TextEditingController();
HashSet<int> alreadyReportedOpened = HashSet<int>();
int sendTextMessages = 0;
late Contact user;
@override
void initState() {
super.initState();
user = widget.user;
_loadAsync(updateOpenStatus: true);
}
Future _loadAsync({bool updateOpenStatus = false}) async {
// if (_messages.isEmpty || updateOpenStatus) {
if (sendTextMessages <= 0) {
_messages = await DbMessages.getAllMessagesForUser(user.userId.toInt());
} else {
sendTextMessages--;
// will not update older message states like when they now downloaded...
int lastMessageId = _messages.first.messageId;
List<DbMessage> toAppend =
await DbMessages.getAllMessagesForUserWithHigherMessageId(
user.userId.toInt(), lastMessageId);
_messages.insertAll(0, toAppend);
}
if (updateOpenStatus) {
_messages.where((x) => x.messageOpenedAt == null).forEach((message) {
if (message.messageOtherId != null &&
message.messageContent is TextMessageContent) {
if (!alreadyReportedOpened.contains(message.messageOtherId!)) {
userOpenedOtherMessage(
message.otherUserId, message.messageOtherId!);
flutterLocalNotificationsPlugin.cancel(message.messageId);
alreadyReportedOpened.add(message.messageOtherId!);
}
}
});
}
try {
if (context.mounted) {
setState(() {});
}
} catch (e) {
// state should be disposed
return;
}
context
.read<MessagesChangeProvider>()
.loadMessagesForUser(user.userId.toInt());
}
Future _sendMessage() async {
sendTextMessages++;
String text = newMessageController.text;
if (text == "") return;
if (newMessageController.text == "") return;
setState(() {});
await sendTextMessage(user.userId, newMessageController.text);
newMessageController.clear();
setState(() {});
}
@override
@ -195,14 +156,27 @@ class _ChatItemDetailsViewState extends State<ChatItemDetailsView> {
.watch<ContactChangeProvider>()
.allContacts
.firstWhere((c) => c.userId == widget.user.userId);
final changeCounter = context.watch<MessagesChangeProvider>().changeCounter;
if (changeCounter.containsKey(user.userId.toInt())) {
if (changeCounter[user.userId.toInt()] != lastChangeCounter) {
_loadAsync(updateOpenStatus: true);
lastChangeCounter = changeCounter[user.userId.toInt()]!;
setState(() {});
List<DbMessage> messages = context
.watch<MessagesChangeProvider>()
.allMessagesFromUser[user.userId.toInt()] ??
[];
messages.where((x) => x.messageOpenedAt == null).forEach((message) {
if (message.messageOtherId != null &&
message.messageContent is TextMessageContent) {
if (!alreadyReportedOpened.contains(message.messageOtherId!)) {
setState(() {
// so the _loadAsync will not be called again by this update
lastChangeCounter++;
});
userOpenedOtherMessage(message.otherUserId, message.messageOtherId!);
flutterLocalNotificationsPlugin.cancel(message.messageId);
alreadyReportedOpened.add(message.messageOtherId!);
}
}
}
});
return Scaffold(
appBar: AppBar(
title: GestureDetector(
@ -223,7 +197,7 @@ class _ChatItemDetailsViewState extends State<ChatItemDetailsView> {
color: Colors.transparent,
child: Row(
children: [
Text(user.displayName),
Text(user.userId.toString()),
SizedBox(width: 10),
VerifiedShield(user),
],
@ -238,27 +212,27 @@ class _ChatItemDetailsViewState extends State<ChatItemDetailsView> {
children: [
Expanded(
child: ListView.builder(
itemCount: _messages.length, // Number of items in the list
itemCount: messages.length, // Number of items in the list
reverse: true,
itemBuilder: (context, i) {
bool lastMessageFromSameUser = false;
if (i > 0) {
lastMessageFromSameUser =
(_messages[i - 1].messageOtherId == null &&
_messages[i].messageOtherId == null) ||
(_messages[i - 1].messageOtherId != null &&
_messages[i].messageOtherId != null);
(messages[i - 1].messageOtherId == null &&
messages[i].messageOtherId == null) ||
(messages[i - 1].messageOtherId != null &&
messages[i].messageOtherId != null);
}
if (_messages[i].messageOpenedAt != null) {
if (messages[i].messageOpenedAt != null) {
if ((DateTime.now())
.difference(_messages[i].messageOpenedAt!)
.difference(messages[i].messageOpenedAt!)
.inHours >=
24) {
return Container();
}
}
return ChatListEntry(
_messages[i],
messages[i],
user,
lastMessageFromSameUser,
);