syncConversationMessages method

Future<void> syncConversationMessages({
  1. required int talkMode,
  2. required int toFromId,
  3. int pageSize = 30,
  4. int maxPages = 20,
})

增量同步:用现有 sequence < cursor 接口从最新页向前回填, 直到与本地 max_seq 重叠或无更多数据,结果写入本地库。

Implementation

Future<void> syncConversationMessages({
  required int talkMode,
  required int toFromId,
  int pageSize = 30,
  int maxPages = 20,
}) async {
  if (!_net.isOnline) return;

  final localMax = await _store.maxSequence(
    talkMode: talkMode,
    toFromId: toFromId,
  );

  var cursor = '0';
  var pages = 0;
  var overlapped = false;

  while (pages < maxPages) {
    pages++;
    List<Message> batch;
    try {
      batch = await _fetchRecordsPage(
        talkMode: talkMode,
        toFromId: toFromId,
        cursor: cursor,
        limit: pageSize,
      );
    } catch (e) {
      GoChatLogger.e('syncConversationMessages failed', e);
      return;
    }
    if (batch.isEmpty) break;

    await _store.upsertMessages(batch);

    final nums = batch.map((m) => m.seq).where((n) => n > 0);
    if (nums.isEmpty) break;
    final minInBatch = nums.reduce((a, b) => a < b ? a : b);
    final maxInBatch = nums.reduce((a, b) => a > b ? a : b);

    if (localMax > 0 && minInBatch <= localMax) {
      overlapped = true;
      break;
    }
    // 本地为空:拉一页最新即可种子化
    if (localMax == 0) break;

    if (maxInBatch <= localMax) {
      overlapped = true;
      break;
    }
    cursor = '$minInBatch';
    if (batch.length < pageSize) break;
  }

  if (localMax > 0 && !overlapped && pages >= maxPages) {
    GoChatLogger.d(
      'syncConversationMessages: gap may remain '
      '(localMax=$localMax pages=$pages)',
    );
  }
}