feat: анимации с реанимации
This commit is contained in:
Vendored
+2
@@ -7,6 +7,7 @@ import '../../models/bot_info.dart';
|
||||
import '../../models/chat_info.dart';
|
||||
import '../../models/contact_info.dart';
|
||||
import '../protocol/opcode_map.dart';
|
||||
import '../storage/chat_members_store.dart';
|
||||
|
||||
Api? _api;
|
||||
|
||||
@@ -336,6 +337,7 @@ class ChatInfoFetch {
|
||||
if (chats is! List || chats.isEmpty) return null;
|
||||
final first = chats.first;
|
||||
if (first is! Map) return null;
|
||||
ChatMembersStore.instance.applyChatPayload(first);
|
||||
return ChatInfo.fromMap(Map<String, dynamic>.from(first));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,6 +14,24 @@ extension ChatActivityLabel on ChatActivity {
|
||||
ChatActivity chatActivityFromType(dynamic type) =>
|
||||
type == 'STICKER' ? ChatActivity.sticker : ChatActivity.typing;
|
||||
|
||||
class ChatActivitySnapshot {
|
||||
const ChatActivitySnapshot({required this.activity, required this.userIds});
|
||||
|
||||
final ChatActivity activity;
|
||||
final List<int> userIds;
|
||||
|
||||
String get label => activity.label;
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) =>
|
||||
other is ChatActivitySnapshot &&
|
||||
other.activity == activity &&
|
||||
listEquals(other.userIds, userIds);
|
||||
|
||||
@override
|
||||
int get hashCode => Object.hash(activity, Object.hashAll(userIds));
|
||||
}
|
||||
|
||||
class ChatActivityStore {
|
||||
ChatActivityStore._();
|
||||
|
||||
@@ -23,15 +41,17 @@ class ChatActivityStore {
|
||||
|
||||
final Map<int, Map<int, ChatActivity>> _users = {};
|
||||
final Map<int, Map<int, Timer>> _timers = {};
|
||||
final Map<int, ValueNotifier<ChatActivity?>> _notifiers = {};
|
||||
final Map<int, ValueNotifier<ChatActivitySnapshot?>> _notifiers = {};
|
||||
|
||||
ValueListenable<ChatActivity?> listenable(int chatId) =>
|
||||
ValueListenable<ChatActivitySnapshot?> listenable(int chatId) =>
|
||||
_notifiers.putIfAbsent(
|
||||
chatId,
|
||||
() => ValueNotifier<ChatActivity?>(_current(chatId)),
|
||||
() => ValueNotifier<ChatActivitySnapshot?>(_current(chatId)),
|
||||
);
|
||||
|
||||
ChatActivity? activity(int chatId) => _current(chatId);
|
||||
ChatActivitySnapshot? snapshot(int chatId) => _current(chatId);
|
||||
|
||||
ChatActivity? activity(int chatId) => _current(chatId)?.activity;
|
||||
|
||||
void mark(int chatId, int userId, ChatActivity activity) {
|
||||
final timers = _timers.putIfAbsent(chatId, () => <int, Timer>{});
|
||||
@@ -64,13 +84,17 @@ class ChatActivityStore {
|
||||
_sync(chatId);
|
||||
}
|
||||
|
||||
ChatActivity? _current(int chatId) {
|
||||
ChatActivitySnapshot? _current(int chatId) {
|
||||
final users = _users[chatId];
|
||||
if (users == null || users.isEmpty) return null;
|
||||
for (final activity in users.values) {
|
||||
if (activity == ChatActivity.typing) return ChatActivity.typing;
|
||||
}
|
||||
return ChatActivity.sticker;
|
||||
final leading = users.values.contains(ChatActivity.typing)
|
||||
? ChatActivity.typing
|
||||
: ChatActivity.sticker;
|
||||
final ids = <int>[];
|
||||
users.forEach((userId, activity) {
|
||||
if (activity == leading) ids.add(userId);
|
||||
});
|
||||
return ChatActivitySnapshot(activity: leading, userIds: ids);
|
||||
}
|
||||
|
||||
void _sync(int chatId) {
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
import 'package:flutter/foundation.dart';
|
||||
|
||||
class ChatMembersStore {
|
||||
ChatMembersStore._();
|
||||
|
||||
static final ChatMembersStore instance = ChatMembersStore._();
|
||||
|
||||
final Map<int, int> _counts = {};
|
||||
final Map<int, ValueNotifier<int?>> _notifiers = {};
|
||||
|
||||
ValueListenable<int?> listenable(int chatId) => _notifiers.putIfAbsent(
|
||||
chatId,
|
||||
() => ValueNotifier<int?>(_counts[chatId]),
|
||||
);
|
||||
|
||||
int? count(int chatId) => _counts[chatId];
|
||||
|
||||
void setCount(int chatId, int? count) {
|
||||
if (count == null || count < 0) return;
|
||||
if (_counts[chatId] == count) return;
|
||||
_counts[chatId] = count;
|
||||
_notifiers[chatId]?.value = count;
|
||||
}
|
||||
|
||||
void adjust(int chatId, int delta) {
|
||||
final current = _counts[chatId];
|
||||
if (current == null || delta == 0) return;
|
||||
final next = current + delta;
|
||||
setCount(chatId, next < 0 ? 0 : next);
|
||||
}
|
||||
|
||||
void applyChatPayload(Object? chat) {
|
||||
if (chat is! Map) return;
|
||||
final id = chat['id'];
|
||||
final count = chat['participantsCount'];
|
||||
if (id is int && count is int) setCount(id, count);
|
||||
}
|
||||
|
||||
void clear() {
|
||||
_counts.clear();
|
||||
for (final notifier in _notifiers.values) {
|
||||
notifier.value = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user