feat(chats_screen): Real-time работа с lastMsg, галочки.
This commit is contained in:
Vendored
+10
@@ -135,6 +135,16 @@ class PresenceFetch {
|
||||
static void invalidate(int id) => _cache.invalidate(id);
|
||||
static void clear() => _cache.clear();
|
||||
|
||||
static void primeAll(Map<dynamic, dynamic> presence) {
|
||||
final now = DateTime.now();
|
||||
presence.forEach((key, value) {
|
||||
if (value is! Map) return;
|
||||
final id = key is int ? key : int.tryParse(key.toString());
|
||||
if (id == null) return;
|
||||
_cache.putValue(id, Map<String, dynamic>.from(value), at: now);
|
||||
});
|
||||
}
|
||||
|
||||
static Future<Map<String, dynamic>?> _fetch(int id) async {
|
||||
final results = await _fetchBatch([id]);
|
||||
return results[id];
|
||||
|
||||
@@ -185,7 +185,7 @@ class AppDatabase {
|
||||
await _migrateLegacyDb(target);
|
||||
return openDatabase(
|
||||
target,
|
||||
version: 11,
|
||||
version: 12,
|
||||
onOpen: (db) => db.execute('PRAGMA foreign_keys = ON'),
|
||||
onCreate: (db, _) => _createTables(db),
|
||||
onUpgrade: (db, oldVersion, newVersion) async {
|
||||
@@ -238,6 +238,11 @@ class AppDatabase {
|
||||
if (oldVersion < 11) {
|
||||
await _createIndexes(db);
|
||||
}
|
||||
if (oldVersion < 12) {
|
||||
await db.execute(
|
||||
'ALTER TABLE chats_cache ADD COLUMN last_msg_status TEXT',
|
||||
);
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
@@ -313,6 +318,7 @@ class AppDatabase {
|
||||
last_msg_time INTEGER,
|
||||
last_msg_text TEXT,
|
||||
last_msg_sender INTEGER,
|
||||
last_msg_status TEXT,
|
||||
unread_count INTEGER NOT NULL DEFAULT 0,
|
||||
last_event_time INTEGER NOT NULL DEFAULT 0,
|
||||
cached_at INTEGER NOT NULL,
|
||||
@@ -480,14 +486,19 @@ class AppDatabase {
|
||||
if (rows.isEmpty) return;
|
||||
try {
|
||||
final db = await _instance;
|
||||
final cols = rows.first.keys.toList();
|
||||
final placeholders = List.filled(cols.length, '?').join(', ');
|
||||
final updates = cols
|
||||
.where((c) => c != 'id' && c != 'account_id')
|
||||
.map((c) => '$c = excluded.$c')
|
||||
.join(', ');
|
||||
final sql = 'INSERT INTO chats_cache (${cols.join(', ')}) '
|
||||
'VALUES ($placeholders) '
|
||||
'ON CONFLICT(id, account_id) DO UPDATE SET $updates';
|
||||
await db.transaction((txn) async {
|
||||
final batch = txn.batch();
|
||||
for (final row in rows) {
|
||||
batch.insert(
|
||||
'chats_cache',
|
||||
row,
|
||||
conflictAlgorithm: ConflictAlgorithm.replace,
|
||||
);
|
||||
batch.rawInsert(sql, cols.map((c) => row[c]).toList());
|
||||
}
|
||||
await batch.commit(noResult: true);
|
||||
});
|
||||
@@ -661,4 +672,16 @@ class AppDatabase {
|
||||
whereArgs: [accountId, chatId, messageId],
|
||||
);
|
||||
}
|
||||
|
||||
static Future<List<Map<String, dynamic>>> loadPendingMessages(
|
||||
int accountId,
|
||||
) async {
|
||||
final db = await _instance;
|
||||
return db.query(
|
||||
'messages',
|
||||
where: 'account_id = ? AND status = ?',
|
||||
whereArgs: [accountId, 'pending'],
|
||||
orderBy: 'time ASC',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
|
||||
class DraftStore {
|
||||
DraftStore._();
|
||||
|
||||
static final DraftStore instance = DraftStore._();
|
||||
|
||||
static const String _prefsKey = 'chat_drafts';
|
||||
|
||||
final Map<String, String> _drafts = {};
|
||||
final ValueNotifier<int> revision = ValueNotifier(0);
|
||||
bool _loaded = false;
|
||||
|
||||
String _key(int accountId, int chatId) => '$accountId/$chatId';
|
||||
|
||||
Future<void> load() async {
|
||||
if (_loaded) return;
|
||||
_loaded = true;
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
final raw = prefs.getString(_prefsKey);
|
||||
if (raw == null) return;
|
||||
try {
|
||||
final map = jsonDecode(raw);
|
||||
if (map is Map) {
|
||||
map.forEach((k, v) {
|
||||
if (k is String && v is String) _drafts[k] = v;
|
||||
});
|
||||
}
|
||||
} catch (_) {}
|
||||
}
|
||||
|
||||
String? get(int accountId, int chatId) {
|
||||
if (accountId == 0) return null;
|
||||
return _drafts[_key(accountId, chatId)];
|
||||
}
|
||||
|
||||
Future<void> set(int accountId, int chatId, String text) async {
|
||||
if (accountId == 0) return;
|
||||
final key = _key(accountId, chatId);
|
||||
final current = _drafts[key];
|
||||
if (text.trim().isEmpty) {
|
||||
if (current == null) return;
|
||||
_drafts.remove(key);
|
||||
} else {
|
||||
if (current == text) return;
|
||||
_drafts[key] = text;
|
||||
}
|
||||
revision.value++;
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
await prefs.setString(_prefsKey, jsonEncode(_drafts));
|
||||
}
|
||||
|
||||
Future<void> clear(int accountId, int chatId) => set(accountId, chatId, '');
|
||||
}
|
||||
Reference in New Issue
Block a user