relatica/lib/riverpod_controllers/timeline_entry_services.dart

111 wiersze
3.6 KiB
Dart

import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:logging/logging.dart';
import 'package:result_monad/result_monad.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';
import '../models/auth/profile.dart';
import '../models/exec_error.dart';
import '../models/timeline_entry.dart';
import 'networking/friendica_interactions_client_services.dart';
import 'networking/friendica_statuses_client_services.dart';
import 'reshared_via_services.dart';
import 'timeline_services.dart';
part 'timeline_entry_services.g.dart';
@Riverpod(keepAlive: true)
Map<String, TimelineEntry> _timelineEntries(Ref ref, Profile profile) => {};
final _logger = Logger('TimelineEntryManagerProvider');
@Riverpod(keepAlive: true)
class TimelineEntryManager extends _$TimelineEntryManager {
var entryId = '';
@override
Result<TimelineEntry, ExecError> build(Profile profile, String id) {
_logger.finest('Building for $id for $profile');
//ref.cacheFor(const Duration(hours: 1));
entryId = id;
final entry = ref.watch(_timelineEntriesProvider(profile))[id];
if (entry == null) {
_logger.finest('Entry not found for $id for $profile');
return buildErrorResult(
type: ErrorType.notFound,
message: '$id not found',
);
}
_logger.finest('For $id for $profile returning: \n$entry');
return Result.ok(entry);
}
Result<TimelineEntry, ExecError> upsert(TimelineEntry entry) {
_logger.fine('Upserting entry for ${entry.id} for $profile');
if (entry.id != entryId) {
return buildErrorResult(
type: ErrorType.argumentError,
message:
'Trying to add an entry to a provider that does not match the id: $id',
);
} else {
ref.read(_timelineEntriesProvider(profile))[entryId] = entry;
}
if (state.isFailure || entry != state.value) {
state = Result.ok(entry);
ref.invalidateSelf(); //Confirm I need to do this, I don't think I do
}
return state;
}
FutureResult<TimelineEntry, ExecError> toggleFavorited(bool newStatus) async {
final result = await ref
.read(changeFavoriteStatusProvider(profile, entryId, newStatus).future)
.withResult((update) {
_logger.fine('Updating $entryId for $profile to: \n$update');
ref.read(_timelineEntriesProvider(profile))[entryId] = update;
});
if (result.isSuccess) {
state = result.execErrorCast();
}
return state;
}
FutureResult<TimelineEntry, ExecError> resharePost() async {
final result = await ref
.read(resharePostProvider(profile, entryId).future)
.withResult((item) async {
ref
.read(resharedViaProvider(profile, entryId).notifier)
.upsertResharedVia(profile.id);
}).withResult((update) =>
ref.read(_timelineEntriesProvider(profile))[entryId] = update);
state = result.execErrorCast();
return state;
}
FutureResult<TimelineEntry, ExecError> unResharePost() async {
final result = await ref
.read(unResharePostProvider(profile, entryId).future)
.withResult((item) async {
ref
.read(resharedViaProvider(profile, entryId).notifier)
.upsertRemovedSharer(profile.id);
}).withResult((update) =>
ref.read(_timelineEntriesProvider(profile))[entryId] = update);
state = result.execErrorCast();
return state;
}
void remove() {
_logger.finest('Delete item $entryId');
ref.read(_timelineEntriesProvider(profile)).remove(entryId);
ref.read(timelineMaintainerProvider(profile).notifier).sweep(entryId);
ref.invalidateSelf();
}
}