fix: Уведомление приходит, хотя чат открыт. Нет зелёной точки «в сети» в списке чатов. Тап по уведомлению не открывает чат. Реакции на сторис. Пропали галочки в папке «Все».
This commit is contained in:
Vendored
+28
-1
@@ -112,7 +112,10 @@ class ContactInfoFetch {
|
||||
static void clear() => _cache.clear();
|
||||
|
||||
static void putContact(int id, Map<dynamic, dynamic> contact) {
|
||||
_cache.putValue(id, ContactInfo.fromMap(Map<String, dynamic>.from(contact)));
|
||||
_cache.putValue(
|
||||
id,
|
||||
ContactInfo.fromMap(Map<String, dynamic>.from(contact)),
|
||||
);
|
||||
}
|
||||
|
||||
static Future<Map<int, ContactInfo>> getMany(
|
||||
@@ -243,19 +246,43 @@ class PresenceFetch {
|
||||
if (missing.isNotEmpty) {
|
||||
final fetched = await _fetchBatch(missing);
|
||||
final now = DateTime.now();
|
||||
var changed = false;
|
||||
for (final id in missing) {
|
||||
final value = fetched[id];
|
||||
if (value != null) {
|
||||
_cache.putValue(id, value, at: now);
|
||||
_live[id] = value;
|
||||
result[id] = value;
|
||||
changed = true;
|
||||
} else {
|
||||
_cache.markFailed(id, at: now);
|
||||
}
|
||||
}
|
||||
if (changed) revision.value++;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static const _batchSize = 100;
|
||||
|
||||
static Future<void> ensureFor(Iterable<int> ids) async {
|
||||
final wanted = <int>{};
|
||||
for (final id in ids) {
|
||||
if (id <= 0) continue;
|
||||
if (_cache.peek(id) != null) continue;
|
||||
wanted.add(id);
|
||||
}
|
||||
if (wanted.isEmpty) return;
|
||||
final list = wanted.toList();
|
||||
for (var i = 0; i < list.length; i += _batchSize) {
|
||||
final chunk = list.sublist(
|
||||
i,
|
||||
i + _batchSize > list.length ? list.length : i + _batchSize,
|
||||
);
|
||||
await getMany(chunk);
|
||||
}
|
||||
}
|
||||
|
||||
static Future<Map<int, Map<String, dynamic>>> _fetchBatch(
|
||||
List<int> ids,
|
||||
) async {
|
||||
|
||||
@@ -0,0 +1,113 @@
|
||||
import 'dart:async';
|
||||
import 'dart:io' show Platform;
|
||||
|
||||
import 'package:flutter/services.dart';
|
||||
|
||||
import '../../backend/api.dart';
|
||||
import '../../frontend/widgets/max_link_nav.dart';
|
||||
import '../../main.dart';
|
||||
import '../utils/logger.dart';
|
||||
|
||||
class NotificationBridge {
|
||||
NotificationBridge._();
|
||||
static final NotificationBridge instance = NotificationBridge._();
|
||||
|
||||
static const _method = MethodChannel('ru.komet.app/notifications');
|
||||
static const _events = EventChannel('ru.komet.app/notification_events');
|
||||
static const _retryDelay = Duration(milliseconds: 300);
|
||||
static const _maxRetries = 100;
|
||||
|
||||
bool _started = false;
|
||||
bool _ready = false;
|
||||
int _pendingChatId = 0;
|
||||
int _activeChatId = 0;
|
||||
int _retriesLeft = 0;
|
||||
Timer? _retry;
|
||||
|
||||
bool get _android {
|
||||
try {
|
||||
return Platform.isAndroid;
|
||||
} catch (_) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void init() {
|
||||
if (_started || !_android) return;
|
||||
_started = true;
|
||||
_events.receiveBroadcastStream().listen(
|
||||
_onEvent,
|
||||
onError: (e) => logger.w('NotificationBridge: events stream error: $e'),
|
||||
);
|
||||
api.stateStream.listen((state) {
|
||||
if (state == SessionState.online) _flushPending();
|
||||
});
|
||||
}
|
||||
|
||||
void markReady() {
|
||||
_ready = true;
|
||||
_flushPending();
|
||||
}
|
||||
|
||||
Future<void> checkInitialChat() async {
|
||||
if (!_android) return;
|
||||
try {
|
||||
_onEvent(await _method.invokeMethod<dynamic>('consumeInitialChat'));
|
||||
} catch (e) {
|
||||
logger.w('NotificationBridge.checkInitialChat: $e');
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> setActiveChat(int chatId) async {
|
||||
if (!_android || chatId <= 0) return;
|
||||
if (_activeChatId == chatId) return;
|
||||
_activeChatId = chatId;
|
||||
try {
|
||||
await _method.invokeMethod<void>('setActiveChat', {'chatId': chatId});
|
||||
} catch (e) {
|
||||
logger.w('NotificationBridge.setActiveChat: $e');
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> clearActiveChat(int chatId) async {
|
||||
if (!_android) return;
|
||||
if (chatId > 0 && _activeChatId != chatId) return;
|
||||
_activeChatId = 0;
|
||||
try {
|
||||
await _method.invokeMethod<void>('clearActiveChat');
|
||||
} catch (e) {
|
||||
logger.w('NotificationBridge.clearActiveChat: $e');
|
||||
}
|
||||
}
|
||||
|
||||
void _onEvent(Object? event) {
|
||||
final chatId = event is int ? event : int.tryParse(event?.toString() ?? '');
|
||||
if (chatId == null || chatId <= 0) return;
|
||||
_pendingChatId = chatId;
|
||||
_retriesLeft = _maxRetries;
|
||||
_flushPending();
|
||||
}
|
||||
|
||||
void _flushPending() {
|
||||
final chatId = _pendingChatId;
|
||||
if (chatId <= 0) return;
|
||||
|
||||
final context = KometApp.navigatorKey.currentContext;
|
||||
if (!_ready || context == null || api.state != SessionState.online) {
|
||||
if (_retriesLeft <= 0) {
|
||||
_pendingChatId = 0;
|
||||
return;
|
||||
}
|
||||
_retriesLeft--;
|
||||
_retry ??= Timer(_retryDelay, () {
|
||||
_retry = null;
|
||||
_flushPending();
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
_pendingChatId = 0;
|
||||
if (_activeChatId == chatId) return;
|
||||
unawaited(openChatById(context, chatId));
|
||||
}
|
||||
}
|
||||
@@ -847,6 +847,25 @@ class AppDatabase {
|
||||
}
|
||||
}
|
||||
|
||||
static Future<void> repairLastMessageSenders(int accountId) async {
|
||||
try {
|
||||
final db = await _instance;
|
||||
await db.rawUpdate(
|
||||
'UPDATE chats_cache SET last_msg_sender = ('
|
||||
' SELECT m.sender_id FROM messages m'
|
||||
' WHERE m.account_id = chats_cache.account_id'
|
||||
' AND m.chat_id = chats_cache.id'
|
||||
' AND m.id = CAST(chats_cache.last_msg_id AS TEXT)'
|
||||
') '
|
||||
'WHERE account_id = ? AND last_msg_sender IS NULL '
|
||||
'AND last_msg_id IS NOT NULL',
|
||||
[accountId],
|
||||
);
|
||||
} catch (e) {
|
||||
logger.w('Не удалось восстановить отправителей последних сообщений: $e');
|
||||
}
|
||||
}
|
||||
|
||||
static Future<List<Map<String, dynamic>>> loadChat(
|
||||
int accountId,
|
||||
int chatId,
|
||||
|
||||
Reference in New Issue
Block a user