import 'package:logging/logging.dart'; import 'package:relatica/models/connection.dart'; import 'package:relatica/models/direct_message_thread.dart'; import 'package:relatica/models/exec_error.dart'; import 'package:result_monad/result_monad.dart'; import 'package:riverpod_annotation/riverpod_annotation.dart'; import '../friendica_client/friendica_client.dart'; import '../friendica_client/paging_data.dart'; import '../globals.dart'; import '../models/auth/oauth_credentials.dart'; import '../models/auth/profile.dart'; import '../models/direct_message.dart'; import '../services/feature_version_checker.dart'; part 'direct_message_services.g.dart'; @Riverpod(keepAlive: true) class DirectMessageThreadIds extends _$DirectMessageThreadIds { static final _logger = Logger('DirectMessageThreadIdsProvider'); late Profile userProfile; @override List build(Profile profile) { userProfile = profile; update(); return []; } Future update() async { final threads = []; await DirectMessagingClient(userProfile) .getDirectMessages(PagingData()) .match( onSuccess: (update) { final newThreads = DirectMessageThread.createThreads(update); for (final t in newThreads) { threads.add(t.parentUri); ref .read(directMessageThreadServiceProvider(userProfile, t.parentUri) .notifier) .update(t); } _logger.fine( 'Updated ${update.length} direct messages, across ${newThreads.length} threads'); }, onError: (error) { _logger.severe('Error getting direct messages: $error'); }, ); state = threads; } FutureResult newThread( Connection receiver, String text) async { if (userProfile.credentials is OAuthCredentials) { final result = getIt() .canUseFeatureResult(RelaticaFeatures.directMessageCreation); if (result.isFailure) { return result.errorCast(); } } final result = await DirectMessagingClient(userProfile).postDirectMessage( null, receiver.id, text, ); result.match(onSuccess: (newMessage) { DirectMessageThread.createThreads([newMessage]).forEach((thread) { state = [...state, thread.parentUri]; ref .read(directMessageThreadServiceProvider( userProfile, thread.parentUri) .notifier) .update(thread); }); }, onError: (error) { _logger.severe('Error getting direct messages: $error'); }); ref.invalidateSelf(); return result.execErrorCast(); } } @Riverpod(keepAlive: true) class DirectMessageThreadService extends _$DirectMessageThreadService { static final _logger = Logger('DirectMessageThreadServiceProvider'); String threadId = ''; @override DirectMessageThread build(Profile profile, String id) { _logger.severe('build id = $id'); threadId = id; state = DirectMessageThread( messages: [], participants: [], title: 'Uninitialized', parentUri: '', ); return state; } void update(DirectMessageThread thread) { print('OldThread == NewThread? ${state == thread}'); state = thread; } FutureResult newReplyMessage( DirectMessage original, String text) async { if (!state.messages.contains(original)) { final error = 'Message is not for this thread: ${state.parentUri}, $original'; _logger.severe(error); return buildErrorResult( type: ErrorType.notFound, message: error, ); } if (profile.credentials is OAuthCredentials) { final result = getIt() .canUseFeatureResult(RelaticaFeatures.directMessageCreation); if (result.isFailure) { return result.errorCast(); } } final result = await DirectMessagingClient(profile).postDirectMessage( original.id, original.senderId, text, ); result.match(onSuccess: (newMessage) { state.messages.add(newMessage); }, onError: (error) { _logger.severe('Error getting direct messages: $error'); }); update(state); return result.execErrorCast(); } Future markMessageRead(DirectMessage m) async { final oldIndex = state.messages.indexOf(m); if (oldIndex < 0) { _logger.severe('Message is not for this thread: ${state.parentUri}, $m'); return; } await DirectMessagingClient(profile).markDirectMessageRead(m).match( onSuccess: (updatedItem) { final newState = state.deepCopy(); newState.messages[oldIndex] = updatedItem; update(newState); }, onError: (error) { _logger.severe('Error getting direct messages: $error'); }, ); } }