import 'dart:collection'; import 'package:flutter/foundation.dart'; import 'timeline_identifiers.dart'; const defaultLowestId = 9223372036854775807; const defaultHighestId = 0; enum InsertionType { beginning, end, } class Timeline { final TimelineIdentifiers timelineId; final List _postIds = []; int _lowestStatusId = defaultLowestId; int _highestStatusId = defaultHighestId; int get highestStatusId => _highestStatusId; int get lowestStatusId => _lowestStatusId; Timeline(this.timelineId, {List? initialPostIds}) { if (initialPostIds != null) { _postIds.addAll(initialPostIds); } } List get posts => UnmodifiableListView(_postIds); Timeline addOrUpdate( List newIds, { required InsertionType insertionType, }) { final newIdsSet = Set.from(newIds); final updatedIds = _postIds.where((i) => !newIdsSet.contains(i)).toList(); for (final idString in newIds) { final id = int.parse(idString); if (_lowestStatusId > id) { _lowestStatusId = id; } if (_highestStatusId < id) { _highestStatusId = id; } } switch (insertionType) { case InsertionType.beginning: updatedIds.insertAll(0, newIds); break; case InsertionType.end: updatedIds.addAll(newIds); break; } final existingIds = {}; for (int i = 0; i < updatedIds.length; i++) { final id = updatedIds[i]; if (existingIds.contains(id)) { updatedIds.removeAt(i); } else { existingIds.add(id); } } updatedIds.sort((p1, p2) { final id1 = num.parse(p1); final id2 = num.parse(p2); return id2.compareTo(id1); }); return Timeline(timelineId, initialPostIds: updatedIds) .._lowestStatusId = lowestStatusId .._highestStatusId = highestStatusId; } bool removeTimelineEntry(String id) { return _postIds.remove(id); } void clear() { _postIds.clear(); _lowestStatusId = defaultLowestId; _highestStatusId = defaultHighestId; } @override bool operator ==(Object other) => identical(this, other) || other is Timeline && runtimeType == other.runtimeType && timelineId == other.timelineId && listEquals(_postIds, other._postIds); @override int get hashCode => timelineId.hashCode ^ Object.hashAll(_postIds); }