mirror of
https://github.com/twonlyapp/twonly-app.git
synced 2026-01-15 19:58:41 +00:00
fix #5
This commit is contained in:
parent
ea7b29f594
commit
a121aa6f23
3 changed files with 55 additions and 68 deletions
|
|
@ -158,12 +158,12 @@ class _MyAppState extends State<MyApp> with WidgetsBindingObserver {
|
||||||
}
|
}
|
||||||
|
|
||||||
Future _stopService() async {
|
Future _stopService() async {
|
||||||
FlutterForegroundTask.sendDataToTask("");
|
|
||||||
await FlutterForegroundTask.stopService();
|
|
||||||
if (context.mounted) {
|
if (context.mounted) {
|
||||||
context.read<MessagesChangeProvider>().init();
|
context.read<MessagesChangeProvider>().init(afterPaused: true);
|
||||||
context.read<ContactChangeProvider>().update();
|
context.read<ContactChangeProvider>().update();
|
||||||
}
|
}
|
||||||
|
FlutterForegroundTask.sendDataToTask("");
|
||||||
|
await FlutterForegroundTask.stopService();
|
||||||
if (!apiProvider.isAuthenticated) {
|
if (!apiProvider.isAuthenticated) {
|
||||||
apiProvider.connect();
|
apiProvider.connect();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,10 +7,13 @@ import 'package:twonly/src/utils/misc.dart';
|
||||||
/// for every contact.
|
/// for every contact.
|
||||||
class MessagesChangeProvider with ChangeNotifier, DiagnosticableTreeMixin {
|
class MessagesChangeProvider with ChangeNotifier, DiagnosticableTreeMixin {
|
||||||
final Map<int, DbMessage> _lastMessage = <int, DbMessage>{};
|
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> _changeCounter = <int, int>{};
|
||||||
final Map<int, int> _flamesCounter = <int, int>{};
|
final Map<int, int> _flamesCounter = <int, int>{};
|
||||||
|
|
||||||
Map<int, DbMessage> get lastMessage => _lastMessage;
|
Map<int, DbMessage> get lastMessage => _lastMessage;
|
||||||
|
Map<int, List<DbMessage>> get allMessagesFromUser => _allMessagesFromUser;
|
||||||
Map<int, int> get changeCounter => _changeCounter;
|
Map<int, int> get changeCounter => _changeCounter;
|
||||||
Map<int, int> get flamesCounter => _flamesCounter;
|
Map<int, int> get flamesCounter => _flamesCounter;
|
||||||
|
|
||||||
|
|
@ -20,15 +23,20 @@ class MessagesChangeProvider with ChangeNotifier, DiagnosticableTreeMixin {
|
||||||
if (last != null) {
|
if (last != null) {
|
||||||
_lastMessage[last.otherUserId] = last;
|
_lastMessage[last.otherUserId] = last;
|
||||||
}
|
}
|
||||||
if (!changeCounter.containsKey(targetUserId)) {
|
|
||||||
changeCounter[targetUserId] = 0;
|
|
||||||
}
|
|
||||||
changeCounter[targetUserId] = changeCounter[targetUserId]! + 1;
|
|
||||||
flamesCounter[targetUserId] = await getFlamesForOtherUser(targetUserId);
|
flamesCounter[targetUserId] = await getFlamesForOtherUser(targetUserId);
|
||||||
notifyListeners();
|
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
|
// load everything from the database
|
||||||
List<Contact> allContacts = await DbContacts.getUsers();
|
List<Contact> allContacts = await DbContacts.getUsers();
|
||||||
for (Contact contact in allContacts) {
|
for (Contact contact in allContacts) {
|
||||||
|
|
@ -41,5 +49,10 @@ class MessagesChangeProvider with ChangeNotifier, DiagnosticableTreeMixin {
|
||||||
await getFlamesForOtherUser(contact.userId.toInt());
|
await getFlamesForOtherUser(contact.userId.toInt());
|
||||||
}
|
}
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
|
if (afterPaused) {
|
||||||
|
for (int targetUserId in _allMessagesFromUser.keys) {
|
||||||
|
loadMessagesForUser(targetUserId, force: true);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -129,64 +129,25 @@ class ChatItemDetailsView extends StatefulWidget {
|
||||||
}
|
}
|
||||||
|
|
||||||
class _ChatItemDetailsViewState extends State<ChatItemDetailsView> {
|
class _ChatItemDetailsViewState extends State<ChatItemDetailsView> {
|
||||||
List<DbMessage> _messages = [];
|
|
||||||
int lastChangeCounter = 0;
|
int lastChangeCounter = 0;
|
||||||
final TextEditingController newMessageController = TextEditingController();
|
final TextEditingController newMessageController = TextEditingController();
|
||||||
HashSet<int> alreadyReportedOpened = HashSet<int>();
|
HashSet<int> alreadyReportedOpened = HashSet<int>();
|
||||||
int sendTextMessages = 0;
|
|
||||||
late Contact user;
|
late Contact user;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
user = widget.user;
|
user = widget.user;
|
||||||
_loadAsync(updateOpenStatus: true);
|
context
|
||||||
}
|
.read<MessagesChangeProvider>()
|
||||||
|
.loadMessagesForUser(user.userId.toInt());
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Future _sendMessage() async {
|
Future _sendMessage() async {
|
||||||
sendTextMessages++;
|
if (newMessageController.text == "") return;
|
||||||
String text = newMessageController.text;
|
setState(() {});
|
||||||
if (text == "") return;
|
|
||||||
await sendTextMessage(user.userId, newMessageController.text);
|
await sendTextMessage(user.userId, newMessageController.text);
|
||||||
newMessageController.clear();
|
newMessageController.clear();
|
||||||
setState(() {});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|
@ -195,14 +156,27 @@ class _ChatItemDetailsViewState extends State<ChatItemDetailsView> {
|
||||||
.watch<ContactChangeProvider>()
|
.watch<ContactChangeProvider>()
|
||||||
.allContacts
|
.allContacts
|
||||||
.firstWhere((c) => c.userId == widget.user.userId);
|
.firstWhere((c) => c.userId == widget.user.userId);
|
||||||
final changeCounter = context.watch<MessagesChangeProvider>().changeCounter;
|
|
||||||
if (changeCounter.containsKey(user.userId.toInt())) {
|
List<DbMessage> messages = context
|
||||||
if (changeCounter[user.userId.toInt()] != lastChangeCounter) {
|
.watch<MessagesChangeProvider>()
|
||||||
_loadAsync(updateOpenStatus: true);
|
.allMessagesFromUser[user.userId.toInt()] ??
|
||||||
lastChangeCounter = changeCounter[user.userId.toInt()]!;
|
[];
|
||||||
setState(() {});
|
|
||||||
|
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(
|
return Scaffold(
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
title: GestureDetector(
|
title: GestureDetector(
|
||||||
|
|
@ -223,7 +197,7 @@ class _ChatItemDetailsViewState extends State<ChatItemDetailsView> {
|
||||||
color: Colors.transparent,
|
color: Colors.transparent,
|
||||||
child: Row(
|
child: Row(
|
||||||
children: [
|
children: [
|
||||||
Text(user.displayName),
|
Text(user.userId.toString()),
|
||||||
SizedBox(width: 10),
|
SizedBox(width: 10),
|
||||||
VerifiedShield(user),
|
VerifiedShield(user),
|
||||||
],
|
],
|
||||||
|
|
@ -238,27 +212,27 @@ class _ChatItemDetailsViewState extends State<ChatItemDetailsView> {
|
||||||
children: [
|
children: [
|
||||||
Expanded(
|
Expanded(
|
||||||
child: ListView.builder(
|
child: ListView.builder(
|
||||||
itemCount: _messages.length, // Number of items in the list
|
itemCount: messages.length, // Number of items in the list
|
||||||
reverse: true,
|
reverse: true,
|
||||||
itemBuilder: (context, i) {
|
itemBuilder: (context, i) {
|
||||||
bool lastMessageFromSameUser = false;
|
bool lastMessageFromSameUser = false;
|
||||||
if (i > 0) {
|
if (i > 0) {
|
||||||
lastMessageFromSameUser =
|
lastMessageFromSameUser =
|
||||||
(_messages[i - 1].messageOtherId == null &&
|
(messages[i - 1].messageOtherId == null &&
|
||||||
_messages[i].messageOtherId == null) ||
|
messages[i].messageOtherId == null) ||
|
||||||
(_messages[i - 1].messageOtherId != null &&
|
(messages[i - 1].messageOtherId != null &&
|
||||||
_messages[i].messageOtherId != null);
|
messages[i].messageOtherId != null);
|
||||||
}
|
}
|
||||||
if (_messages[i].messageOpenedAt != null) {
|
if (messages[i].messageOpenedAt != null) {
|
||||||
if ((DateTime.now())
|
if ((DateTime.now())
|
||||||
.difference(_messages[i].messageOpenedAt!)
|
.difference(messages[i].messageOpenedAt!)
|
||||||
.inHours >=
|
.inHours >=
|
||||||
24) {
|
24) {
|
||||||
return Container();
|
return Container();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ChatListEntry(
|
return ChatListEntry(
|
||||||
_messages[i],
|
messages[i],
|
||||||
user,
|
user,
|
||||||
lastMessageFromSameUser,
|
lastMessageFromSameUser,
|
||||||
);
|
);
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue