2024-12-01 19:57:47 +00:00
|
|
|
import 'package:logging/logging.dart';
|
|
|
|
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
|
|
|
|
|
|
|
import '../models/auth/profile.dart';
|
|
|
|
import '../models/timeline.dart';
|
|
|
|
import '../models/timeline_identifiers.dart';
|
|
|
|
import 'entry_tree_item_services.dart';
|
|
|
|
|
|
|
|
part 'timeline_services.g.dart';
|
|
|
|
|
|
|
|
enum TimelineRefreshType {
|
|
|
|
refresh,
|
|
|
|
loadOlder,
|
|
|
|
loadNewer,
|
|
|
|
}
|
|
|
|
|
2024-12-19 04:12:17 +00:00
|
|
|
final _tcLogger = Logger('TimelineCleanerProvider');
|
|
|
|
|
|
|
|
@Riverpod(keepAlive: true)
|
|
|
|
class TimelineCleaner extends _$TimelineCleaner {
|
|
|
|
@override
|
|
|
|
List<TimelineIdentifiers> build(Profile profile) {
|
|
|
|
return [];
|
|
|
|
}
|
|
|
|
|
|
|
|
void add(TimelineIdentifiers timelineId) {
|
|
|
|
_tcLogger.fine('Adding timeline: $timelineId');
|
|
|
|
state.add(timelineId);
|
|
|
|
ref.notifyListeners();
|
|
|
|
}
|
|
|
|
|
|
|
|
void sweep(String statusId) {
|
|
|
|
for (final t in state) {
|
|
|
|
final result = ref
|
|
|
|
.read(timelineManagerProvider(profile, t).notifier)
|
|
|
|
.removeTimelineEntry(statusId);
|
|
|
|
_tcLogger.finest(
|
|
|
|
'Attempting to remove $statusId from $t but was it there? $result');
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
final _tmpLogger = Logger('TimelineManagerProvider');
|
|
|
|
|
2024-12-01 19:57:47 +00:00
|
|
|
@Riverpod(keepAlive: true)
|
|
|
|
class TimelineManager extends _$TimelineManager {
|
|
|
|
@override
|
2024-12-17 16:43:28 +00:00
|
|
|
Timeline build(Profile profile, TimelineIdentifiers timelineId) {
|
|
|
|
_tmpLogger.info('Building for $profile for $timelineId');
|
2024-12-19 04:12:17 +00:00
|
|
|
Future.microtask(() async =>
|
|
|
|
ref.read(timelineCleanerProvider(profile).notifier).add(timelineId));
|
2024-12-01 19:57:47 +00:00
|
|
|
return Timeline(timelineId);
|
|
|
|
}
|
|
|
|
|
|
|
|
Future<void> updateTimeline(
|
|
|
|
TimelineRefreshType refreshType,
|
|
|
|
) async {
|
|
|
|
_tmpLogger.info(
|
2024-12-17 16:43:28 +00:00
|
|
|
'Updating w/$refreshType for timeline $timelineId for profile $profile ');
|
2024-12-01 19:57:47 +00:00
|
|
|
late final int lowestId;
|
|
|
|
late final int highestId;
|
|
|
|
late final InsertionType insertionType;
|
|
|
|
|
|
|
|
switch (refreshType) {
|
|
|
|
case TimelineRefreshType.refresh:
|
|
|
|
lowestId = 0;
|
|
|
|
highestId = 0;
|
|
|
|
insertionType = InsertionType.end;
|
|
|
|
break;
|
|
|
|
case TimelineRefreshType.loadOlder:
|
|
|
|
lowestId = state.lowestStatusId;
|
|
|
|
highestId = 0;
|
|
|
|
insertionType = InsertionType.end;
|
|
|
|
break;
|
|
|
|
case TimelineRefreshType.loadNewer:
|
|
|
|
lowestId = 0;
|
|
|
|
highestId = state.highestStatusId;
|
|
|
|
insertionType = InsertionType.beginning;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
(await ref
|
2024-12-17 16:43:28 +00:00
|
|
|
.read(timelineUpdaterProvider(profile).notifier)
|
2024-12-01 19:57:47 +00:00
|
|
|
.updateTimeline(timelineId, lowestId, highestId))
|
|
|
|
.match(onSuccess: (posts) {
|
|
|
|
_tmpLogger
|
|
|
|
.finest('Posts returned for adding to $timelineId: ${posts.length}');
|
|
|
|
final oldState = state;
|
|
|
|
final newState = state = state.addOrUpdate(
|
|
|
|
posts.map((p) => p.id).toList(),
|
|
|
|
insertionType: insertionType,
|
|
|
|
);
|
|
|
|
_tmpLogger.finest(
|
|
|
|
'Old post count: ${oldState.posts.length}, New Post count: ${newState.posts.length}');
|
|
|
|
_tmpLogger.finest('Old state == New state? ${oldState == newState}');
|
|
|
|
}, onError: (error) {
|
|
|
|
_tmpLogger.severe('Error updating timeline: $timelineId}');
|
|
|
|
});
|
|
|
|
}
|
2024-12-19 04:12:17 +00:00
|
|
|
|
|
|
|
bool removeTimelineEntry(String id) {
|
|
|
|
final hadItem = state.removeTimelineEntry(id);
|
|
|
|
if (hadItem) {
|
|
|
|
ref.notifyListeners();
|
|
|
|
}
|
|
|
|
_tmpLogger.finest('Remove entry $id? $hadItem');
|
|
|
|
|
|
|
|
return hadItem;
|
|
|
|
}
|
2024-12-01 19:57:47 +00:00
|
|
|
}
|