2024-10-02 17:17:48 +00:00
|
|
|
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');
|
|
|
|
|
|
|
|
@override
|
|
|
|
List<String> build(Profile profile) {
|
|
|
|
update();
|
|
|
|
return [];
|
|
|
|
}
|
|
|
|
|
|
|
|
Future<void> update() async {
|
|
|
|
final threads = <String>[];
|
2024-12-07 02:33:51 +00:00
|
|
|
await DirectMessagingClient(profile).getDirectMessages(PagingData()).match(
|
2024-10-02 17:17:48 +00:00
|
|
|
onSuccess: (update) {
|
2024-12-07 02:33:51 +00:00
|
|
|
final newThreads =
|
|
|
|
DirectMessageThread.createThreads(ref, profile, update);
|
2024-10-02 17:17:48 +00:00
|
|
|
for (final t in newThreads) {
|
|
|
|
threads.add(t.parentUri);
|
|
|
|
ref
|
2024-12-07 02:33:51 +00:00
|
|
|
.read(directMessageThreadServiceProvider(profile, t.parentUri)
|
2024-10-02 17:17:48 +00:00
|
|
|
.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<DirectMessage, ExecError> newThread(
|
|
|
|
Connection receiver, String text) async {
|
2024-12-07 02:33:51 +00:00
|
|
|
if (profile.credentials is OAuthCredentials) {
|
2024-10-02 17:17:48 +00:00
|
|
|
final result = getIt<FriendicaVersionChecker>()
|
|
|
|
.canUseFeatureResult(RelaticaFeatures.directMessageCreation);
|
|
|
|
if (result.isFailure) {
|
|
|
|
return result.errorCast();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-12-07 02:33:51 +00:00
|
|
|
final result = await DirectMessagingClient(profile).postDirectMessage(
|
2024-10-02 17:17:48 +00:00
|
|
|
null,
|
|
|
|
receiver.id,
|
|
|
|
text,
|
|
|
|
);
|
|
|
|
result.match(onSuccess: (newMessage) {
|
2024-12-07 02:33:51 +00:00
|
|
|
DirectMessageThread.createThreads(ref, profile, [newMessage])
|
|
|
|
.forEach((thread) {
|
2024-10-02 17:17:48 +00:00
|
|
|
state = [...state, thread.parentUri];
|
|
|
|
ref
|
2024-12-07 02:33:51 +00:00
|
|
|
.read(directMessageThreadServiceProvider(profile, thread.parentUri)
|
2024-10-02 17:17:48 +00:00
|
|
|
.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) {
|
2024-12-02 01:15:08 +00:00
|
|
|
_logger.finest('build id = $id');
|
2024-10-02 17:17:48 +00:00
|
|
|
threadId = id;
|
|
|
|
state = DirectMessageThread(
|
|
|
|
messages: [],
|
|
|
|
participants: [],
|
|
|
|
title: 'Uninitialized',
|
|
|
|
parentUri: '',
|
|
|
|
);
|
|
|
|
return state;
|
|
|
|
}
|
|
|
|
|
|
|
|
void update(DirectMessageThread thread) {
|
|
|
|
state = thread;
|
|
|
|
}
|
|
|
|
|
|
|
|
FutureResult<DirectMessage, ExecError> 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<FriendicaVersionChecker>()
|
|
|
|
.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<void> 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');
|
|
|
|
},
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|