- Replace full-sync fetchMessages(1:*) with UID SEARCH ALL + UID FETCH so every message gets a reliable UID on all servers - Guard CONDSTORE select on server capability to avoid BAD from servers that do not advertise CONDSTORE/QRESYNC - Add SyncLogEntry model + observeSyncLogs stream to SyncLogRepository - Add SyncLogScreen with per-entry duration/error display - Wire history icon in SettingsScreen → /accounts/:id/sync-log route - Fix FakeImapClient to expose initialized serverInfo via field override Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
52 lines
1.4 KiB
Dart
52 lines
1.4 KiB
Dart
import 'package:drift/drift.dart';
|
|
|
|
import '../../core/repositories/sync_log_repository.dart';
|
|
import '../db/database.dart';
|
|
|
|
class SyncLogRepositoryImpl implements SyncLogRepository {
|
|
SyncLogRepositoryImpl(this._db);
|
|
|
|
final AppDatabase _db;
|
|
|
|
@override
|
|
Future<void> log({
|
|
required String accountId,
|
|
required bool success,
|
|
String? errorMessage,
|
|
required DateTime startedAt,
|
|
required DateTime finishedAt,
|
|
}) async {
|
|
await _db.into(_db.syncLogs).insert(
|
|
SyncLogsCompanion.insert(
|
|
accountId: accountId,
|
|
result: success ? 'ok' : 'error',
|
|
errorMessage: Value(errorMessage),
|
|
startedAt: startedAt,
|
|
finishedAt: finishedAt,
|
|
),
|
|
);
|
|
}
|
|
|
|
@override
|
|
Stream<List<SyncLogEntry>> observeSyncLogs(String accountId) {
|
|
return (_db.select(_db.syncLogs)
|
|
..where((t) => t.accountId.equals(accountId))
|
|
..orderBy([(t) => OrderingTerm.desc(t.startedAt)])
|
|
..limit(100))
|
|
.watch()
|
|
.map(
|
|
(rows) => rows
|
|
.map(
|
|
(r) => SyncLogEntry(
|
|
id: r.id,
|
|
result: r.result,
|
|
errorMessage: r.errorMessage,
|
|
startedAt: r.startedAt,
|
|
finishedAt: r.finishedAt,
|
|
),
|
|
)
|
|
.toList(),
|
|
);
|
|
}
|
|
}
|