mirror of
https://gitlab.com/veilid/veilidchat.git
synced 2025-07-20 13:18:50 -04:00
76 lines
2.4 KiB
Dart
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;
|
|
}
|