2024-12-01 19:57:47 +00:00
|
|
|
import 'package:logging/logging.dart';
|
2024-11-27 21:11:30 +00:00
|
|
|
import 'package:result_monad/result_monad.dart';
|
|
|
|
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
|
|
|
|
2024-12-01 19:57:47 +00:00
|
|
|
import '../friendica_client/friendica_client.dart';
|
2024-11-27 21:11:30 +00:00
|
|
|
import '../models/auth/profile.dart';
|
|
|
|
import '../models/exec_error.dart';
|
|
|
|
import '../models/timeline_entry.dart';
|
2024-12-01 19:57:47 +00:00
|
|
|
import 'reshared_via_services.dart';
|
2024-11-27 21:11:30 +00:00
|
|
|
|
|
|
|
part 'timeline_entry_services.g.dart';
|
|
|
|
|
|
|
|
@Riverpod(keepAlive: true)
|
|
|
|
Map<String, TimelineEntry> _timelineEntries(
|
|
|
|
_TimelineEntriesRef ref, Profile profile) =>
|
|
|
|
{};
|
|
|
|
|
2024-12-01 19:57:47 +00:00
|
|
|
final _logger = Logger('TimelineEntryManagerProvider');
|
|
|
|
|
|
|
|
//TODO Test using cacheFor to let it expire
|
|
|
|
@Riverpod(keepAlive: true)
|
2024-11-27 21:11:30 +00:00
|
|
|
class TimelineEntryManager extends _$TimelineEntryManager {
|
|
|
|
late Profile userProfile;
|
|
|
|
var entryId = '';
|
|
|
|
|
|
|
|
@override
|
|
|
|
Result<TimelineEntry, ExecError> build(Profile profile, String id) {
|
2024-12-01 19:57:47 +00:00
|
|
|
_logger.finest('Building for $id for $profile');
|
|
|
|
//ref.cacheFor(const Duration(hours: 1));
|
2024-11-27 21:11:30 +00:00
|
|
|
entryId = id;
|
|
|
|
userProfile = profile;
|
|
|
|
final entry = ref.watch(_timelineEntriesProvider(profile))[id];
|
|
|
|
if (entry == null) {
|
2024-12-01 19:57:47 +00:00
|
|
|
_logger.finest('Entry not found for $id for $profile');
|
2024-11-27 21:11:30 +00:00
|
|
|
return buildErrorResult(
|
|
|
|
type: ErrorType.notFound,
|
|
|
|
message: '$id not found',
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2024-12-01 19:57:47 +00:00
|
|
|
_logger.finest('For $id for $profile returning: \n$entry');
|
2024-11-27 21:11:30 +00:00
|
|
|
return Result.ok(entry);
|
|
|
|
}
|
|
|
|
|
|
|
|
Result<TimelineEntry, ExecError> upsert(TimelineEntry entry) {
|
2024-12-01 19:57:47 +00:00
|
|
|
_logger.fine('Upserting entry for ${entry.id} for $userProfile');
|
2024-11-27 21:11:30 +00:00
|
|
|
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(userProfile))[entryId] = entry;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (state.isFailure || entry != state.value) {
|
|
|
|
state = Result.ok(entry);
|
2024-12-01 19:57:47 +00:00
|
|
|
ref.invalidateSelf(); //Confirm I need to do this, I don't think I do
|
|
|
|
}
|
|
|
|
|
|
|
|
return state;
|
|
|
|
}
|
|
|
|
|
|
|
|
FutureResult<TimelineEntry, ExecError> toggleFavorited(bool newStatus) async {
|
|
|
|
final interactionClient = InteractionsClient(userProfile);
|
|
|
|
final result = await interactionClient
|
|
|
|
.changeFavoriteStatus(entryId, newStatus)
|
|
|
|
.withResult((update) {
|
|
|
|
_logger.fine('Updating $entryId for $userProfile to: \n$update');
|
|
|
|
ref.read(_timelineEntriesProvider(userProfile))[entryId] = update;
|
|
|
|
});
|
|
|
|
if (result.isSuccess) {
|
|
|
|
state = result.execErrorCast();
|
2024-11-27 21:11:30 +00:00
|
|
|
}
|
2024-12-01 19:57:47 +00:00
|
|
|
return state;
|
|
|
|
}
|
|
|
|
|
|
|
|
FutureResult<TimelineEntry, ExecError> resharePost() async {
|
|
|
|
final client = StatusesClient(profile);
|
|
|
|
final result = await client.resharePost(entryId).withResult((item) async {
|
|
|
|
ref
|
|
|
|
.read(resharedViaProvider(userProfile, entryId).notifier)
|
|
|
|
.upsertResharedVia(profile.id);
|
|
|
|
}).withResult((update) =>
|
|
|
|
ref.read(_timelineEntriesProvider(userProfile))[entryId] = update);
|
|
|
|
|
|
|
|
state = result.execErrorCast();
|
|
|
|
return state;
|
|
|
|
}
|
|
|
|
|
|
|
|
FutureResult<TimelineEntry, ExecError> unResharePost() async {
|
|
|
|
final client = StatusesClient(profile);
|
|
|
|
final result = await client.unResharePost(entryId).withResult((item) async {
|
|
|
|
ref
|
|
|
|
.read(resharedViaProvider(userProfile, entryId).notifier)
|
|
|
|
.upsertRemovedSharer(profile.id);
|
|
|
|
}).withResult((update) =>
|
|
|
|
ref.read(_timelineEntriesProvider(userProfile))[entryId] = update);
|
2024-11-27 21:11:30 +00:00
|
|
|
|
2024-12-01 19:57:47 +00:00
|
|
|
state = result.execErrorCast();
|
2024-11-27 21:11:30 +00:00
|
|
|
return state;
|
|
|
|
}
|
|
|
|
|
|
|
|
void remove() {
|
|
|
|
ref.read(_timelineEntriesProvider(userProfile)).remove(entryId);
|
2024-12-01 19:57:47 +00:00
|
|
|
ref.invalidateSelf();
|
2024-11-27 21:11:30 +00:00
|
|
|
}
|
|
|
|
}
|