veilidchat/lib/chat/cubits/reconciliation/author_input_source.dart
Christien Rioux d1559c949d fix lints
2025-06-05 23:46:46 +02:00

76 lines
2.4 KiB
Dart

import 'dart:math';
import 'package:async_tools/async_tools.dart';
import 'package:fast_immutable_collections/fast_immutable_collections.dart';
import 'package:meta/meta.dart';
import 'package:veilid_support/veilid_support.dart';
import '../../../proto/proto.dart' as proto;
@immutable
class InputWindow {
const InputWindow({required this.elements, required this.firstPosition})
: lastPosition = firstPosition + elements.length - 1,
isEmpty = elements.length == 0,
length = elements.length;
final IList<OnlineElementState<proto.Message>> elements;
final int firstPosition;
final int lastPosition;
final bool isEmpty;
final int length;
}
class AuthorInputSource {
AuthorInputSource.fromDHTLog(DHTLog dhtLog) : _dhtLog = dhtLog;
////////////////////////////////////////////////////////////////////////////
Future<int> getTailPosition() =>
_dhtLog.operate((reader) async => reader.length);
Future<AsyncValue<InputWindow?>> getWindow(
int startPosition, int windowLength) =>
_dhtLog.operate((reader) async {
// Don't allow negative length
if (windowLength <= 0) {
return const AsyncValue.data(null);
}
// Trim if we're beyond input source
var endPosition = startPosition + windowLength - 1;
startPosition = max(startPosition, 0);
endPosition = max(endPosition, 0);
// Get another input batch futher back
try {
Set<int>? offlinePositions;
if (_dhtLog.writer != null) {
offlinePositions = await reader.getOfflinePositions();
}
final messages = await reader.getRangeProtobuf(
proto.Message.fromBuffer, startPosition,
length: endPosition - startPosition + 1);
if (messages == null) {
return const AsyncValue.loading();
}
final elements = messages.indexed
.map((x) => OnlineElementState(
value: x.$2,
isOffline: offlinePositions?.contains(x.$1 + startPosition) ??
false))
.toIList();
final window =
InputWindow(elements: elements, firstPosition: startPosition);
return AsyncValue.data(window);
} on Exception catch (e, st) {
return AsyncValue.error(e, st);
}
});
////////////////////////////////////////////////////////////////////////////
final DHTLog _dhtLog;
}