починил галочки, закрепленные чаты
This commit is contained in:
@@ -132,6 +132,7 @@ class ChatsModule {
|
||||
final chatsConfig = configMap['chats'] is Map
|
||||
? configMap['chats'] as Map
|
||||
: {};
|
||||
|
||||
// Presence for online statuses
|
||||
final presenceMap = data['presence'] is Map ? data['presence'] as Map : {};
|
||||
final cachedAt = DateTime.now().millisecondsSinceEpoch;
|
||||
@@ -272,6 +273,7 @@ class ChatsModule {
|
||||
dontDisturbUntil = (config['dontDisturbUntil'] as int?) ?? 0;
|
||||
}
|
||||
|
||||
|
||||
int seenTime = 0;
|
||||
bool isOnline = false;
|
||||
if (type == 'DIALOG' && otherId != null) {
|
||||
|
||||
@@ -29,7 +29,7 @@ class CachedContact {
|
||||
bool get isOfficial => options.contains('OFFICIAL');
|
||||
bool get isBot => options.contains('BOT');
|
||||
bool get isServiceAccount => options.contains('SERVICE_ACCOUNT');
|
||||
bool get isVerified => isOfficial || isBot || isServiceAccount;
|
||||
bool get isVerified => isOfficial;
|
||||
|
||||
factory CachedContact.fromDbRow(Map<String, dynamic> row) => CachedContact(
|
||||
id: row['id'] as int,
|
||||
|
||||
@@ -8,19 +8,19 @@ import '../../models/attachment.dart';
|
||||
class ContactCache {
|
||||
static final Map<int, String> _nameCache = {};
|
||||
static final Map<int, String> _avatarCache = {};
|
||||
static final Map<int, Set<String>> _optionsCache = {};
|
||||
|
||||
static void put(int id, String name) {
|
||||
_nameCache[id] = name;
|
||||
}
|
||||
static void put(int id, String name) => _nameCache[id] = name;
|
||||
|
||||
static void putAvatar(int id, String? baseUrl) {
|
||||
if (baseUrl != null) {
|
||||
_avatarCache[id] = baseUrl;
|
||||
}
|
||||
if (baseUrl != null) _avatarCache[id] = baseUrl;
|
||||
}
|
||||
|
||||
static void putOptions(int id, Set<String> opts) => _optionsCache[id] = opts;
|
||||
|
||||
static String? get(int id) => _nameCache[id];
|
||||
static String? getAvatar(int id) => _avatarCache[id];
|
||||
static bool isOfficial(int id) => _optionsCache[id]?.contains('OFFICIAL') ?? false;
|
||||
}
|
||||
|
||||
class TranscriptionResult {
|
||||
@@ -545,6 +545,11 @@ class MessagesModule {
|
||||
final baseUrl = contact['baseUrl'] as String?;
|
||||
ContactCache.putAvatar(contactId, baseUrl);
|
||||
|
||||
final rawOpts = contact['options'];
|
||||
if (rawOpts is List) {
|
||||
ContactCache.putOptions(contactId, rawOpts.whereType<String>().toSet());
|
||||
}
|
||||
|
||||
return fullName;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -376,13 +376,21 @@ class _ChatListScreenState extends State<ChatListScreen>
|
||||
}
|
||||
|
||||
List<CachedChat> _chatsForPageIndex(int pageIndex) {
|
||||
if (_folders.isEmpty) return _chats;
|
||||
if (pageIndex < 0 || pageIndex >= _folders.length) return _chats;
|
||||
final folder = _folders[pageIndex];
|
||||
if (FoldersModule.isAllChatsFolder(folder)) return _chats;
|
||||
return _chats
|
||||
.where((c) => FoldersModule.chatMatchesFolder(c, folder))
|
||||
.toList();
|
||||
List<CachedChat> base;
|
||||
if (_folders.isEmpty) {
|
||||
base = _chats;
|
||||
} else if (pageIndex < 0 || pageIndex >= _folders.length) {
|
||||
base = _chats;
|
||||
} else {
|
||||
final folder = _folders[pageIndex];
|
||||
base = FoldersModule.isAllChatsFolder(folder)
|
||||
? _chats
|
||||
: _chats.where((c) => FoldersModule.chatMatchesFolder(c, folder)).toList();
|
||||
}
|
||||
final pinned = base.where((c) => (c.favIndex ?? 0) > 0).toList()
|
||||
..sort((a, b) => a.favIndex!.compareTo(b.favIndex!));
|
||||
final regular = base.where((c) => (c.favIndex ?? 0) <= 0).toList();
|
||||
return [...pinned, ...regular];
|
||||
}
|
||||
|
||||
void _syncFolderChatScrollControllers() {
|
||||
@@ -1088,7 +1096,25 @@ class _ChatListScreenState extends State<ChatListScreen>
|
||||
if (_isInitialLoading) {
|
||||
return _buildChatShimmer();
|
||||
}
|
||||
final chat = chats[index];
|
||||
|
||||
final pinnedCount = chats.where((c) => (c.favIndex ?? 0) > 0).length;
|
||||
final hasSeparator = pinnedCount > 0 && pinnedCount < chats.length;
|
||||
|
||||
// Insert separator row between pinned and regular sections
|
||||
if (hasSeparator && index == pinnedCount) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16),
|
||||
child: Divider(
|
||||
height: 1,
|
||||
thickness: 0.5,
|
||||
color: cs.outlineVariant.withValues(alpha: 0.5),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
final chatIndex = hasSeparator && index > pinnedCount ? index - 1 : index;
|
||||
final chat = chats[chatIndex];
|
||||
final isPinned = (chat.favIndex ?? 0) > 0;
|
||||
|
||||
if (chat.type.isNotEmpty && chat.type == "DIALOG" && chat.id != 0) {
|
||||
final secondId = chat.participants.entries
|
||||
@@ -1097,6 +1123,9 @@ class _ChatListScreenState extends State<ChatListScreen>
|
||||
.key;
|
||||
final name = ContactCache.get(secondId);
|
||||
final avatar = ContactCache.getAvatar(secondId);
|
||||
// ContactCache.isOfficial covers contacts loaded via opcode 32;
|
||||
// chat.isOfficial covers contacts from the login payload.
|
||||
final isVerified = ContactCache.isOfficial(secondId) || chat.isOfficial;
|
||||
|
||||
return _buildChatItem(
|
||||
chat.id.toString(),
|
||||
@@ -1107,7 +1136,8 @@ class _ChatListScreenState extends State<ChatListScreen>
|
||||
isOnline: chat.isOnline,
|
||||
unreadCount: chat.unreadCount,
|
||||
isMuted: chat.dontDisturbUntil > 0,
|
||||
isVerified: chat.isOfficial,
|
||||
isVerified: isVerified,
|
||||
isPinned: isPinned,
|
||||
chatType: "DIALOG",
|
||||
);
|
||||
} else {
|
||||
@@ -1124,7 +1154,7 @@ class _ChatListScreenState extends State<ChatListScreen>
|
||||
if (name?.isNotEmpty == true && chat.id != 0) {
|
||||
fullMsg += "$name: ";
|
||||
}
|
||||
|
||||
|
||||
if (chat.lastMsgText?.isNotEmpty == true) {
|
||||
fullMsg += chat.lastMsgText ?? "";
|
||||
}
|
||||
@@ -1141,10 +1171,11 @@ class _ChatListScreenState extends State<ChatListScreen>
|
||||
unreadCount: chat.unreadCount,
|
||||
isMuted: chat.dontDisturbUntil > 0,
|
||||
isVerified: chat.isOfficial,
|
||||
isPinned: isPinned,
|
||||
chatType: chat.type,
|
||||
);
|
||||
}
|
||||
}, childCount: _isInitialLoading ? 10 : chats.length),
|
||||
}, childCount: _isInitialLoading ? 10 : chats.length + (chats.any((c) => (c.favIndex ?? 0) > 0) && chats.any((c) => (c.favIndex ?? 0) <= 0) ? 1 : 0)),
|
||||
),
|
||||
SliverPadding(
|
||||
padding: EdgeInsets.only(
|
||||
@@ -1760,6 +1791,7 @@ class _ChatListScreenState extends State<ChatListScreen>
|
||||
int unreadCount = 0,
|
||||
bool isMuted = false,
|
||||
bool isVerified = false,
|
||||
bool isPinned = false,
|
||||
String chatType = "CHAT",
|
||||
}) {
|
||||
final cs = Theme.of(context).colorScheme;
|
||||
@@ -1898,6 +1930,15 @@ Navigator.push(
|
||||
weight: 400,
|
||||
),
|
||||
],
|
||||
if (isPinned) ...[
|
||||
const SizedBox(width: 4),
|
||||
Icon(
|
||||
Symbols.keep,
|
||||
color: cs.outlineVariant,
|
||||
size: 14,
|
||||
weight: 400,
|
||||
),
|
||||
],
|
||||
const SizedBox(width: 8),
|
||||
Text(
|
||||
time,
|
||||
|
||||
Reference in New Issue
Block a user