kopia lustrzana https://gitlab.com/mysocialportal/relatica
183 wiersze
5.2 KiB
Dart
183 wiersze
5.2 KiB
Dart
import 'package:logging/logging.dart';
|
|
import 'package:result_monad/result_monad.dart';
|
|
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
|
import 'package:stack_trace/stack_trace.dart';
|
|
|
|
import '../models/auth/oauth_credentials.dart';
|
|
import '../models/auth/profile.dart';
|
|
import '../models/connection.dart';
|
|
import '../models/direct_message.dart';
|
|
import '../models/direct_message_thread.dart';
|
|
import '../models/exec_error.dart';
|
|
import '../models/networking/paging_data.dart';
|
|
import 'feature_checker_services.dart';
|
|
import 'networking/friendica_dms_client_services.dart';
|
|
import 'notification_services.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>[];
|
|
|
|
await ref.read(directMessagesProvider(profile, PagingData()).future).match(
|
|
onSuccess: (update) {
|
|
final newThreads = DirectMessageThread.createThreads(profile, update);
|
|
for (final t in newThreads) {
|
|
threads.add(t.parentUri);
|
|
ref
|
|
.read(directMessageThreadServiceProvider(profile, 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',
|
|
Trace.current(),
|
|
);
|
|
},
|
|
);
|
|
state = threads;
|
|
}
|
|
|
|
FutureResult<DirectMessage, ExecError> newThread(
|
|
Connection receiver, String text) async {
|
|
if (profile.credentials is OAuthCredentials) {
|
|
final result = ref.read(featureCheckResultProvider(
|
|
profile, RelaticaFeatures.directMessageCreation));
|
|
if (result.isFailure) {
|
|
return result.errorCast();
|
|
}
|
|
}
|
|
|
|
final result = await ref.read(postDirectMessageProvider(
|
|
profile,
|
|
null,
|
|
receiver.id,
|
|
text,
|
|
).future);
|
|
result.match(onSuccess: (newMessage) {
|
|
DirectMessageThread.createThreads(profile, [newMessage])
|
|
.forEach((thread) {
|
|
state = [...state, thread.parentUri];
|
|
ref
|
|
.read(directMessageThreadServiceProvider(profile, thread.parentUri)
|
|
.notifier)
|
|
.update(thread);
|
|
});
|
|
}, onError: (error) {
|
|
_logger.severe('Error getting direct messages: $error', Trace.current());
|
|
});
|
|
|
|
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.finest('build id = $id');
|
|
threadId = id;
|
|
state = DirectMessageThread(
|
|
messages: [],
|
|
participantIds: [],
|
|
title: 'Uninitialized',
|
|
parentUri: '',
|
|
);
|
|
return state;
|
|
}
|
|
|
|
void update(DirectMessageThread thread) {
|
|
state = thread;
|
|
}
|
|
|
|
Future<void> refresh() async {
|
|
await ref
|
|
.read(
|
|
updateThreadProvider(profile, state.parentUri, PagingData()).future)
|
|
.withResult((messages) {
|
|
messages.sort((m1, m2) => m1.createdAt.compareTo(m2.createdAt));
|
|
state = state.copy(messages: messages);
|
|
});
|
|
}
|
|
|
|
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, Trace.current());
|
|
return buildErrorResult(
|
|
type: ErrorType.notFound,
|
|
message: error,
|
|
);
|
|
}
|
|
|
|
if (profile.credentials is OAuthCredentials) {
|
|
final result = ref.read(featureCheckResultProvider(
|
|
profile, RelaticaFeatures.directMessageCreation));
|
|
if (result.isFailure) {
|
|
return result.errorCast();
|
|
}
|
|
}
|
|
|
|
final result = await ref.read(postDirectMessageProvider(
|
|
profile,
|
|
original.id,
|
|
original.senderId,
|
|
text,
|
|
).future);
|
|
result.match(onSuccess: (newMessage) {
|
|
state.messages.add(newMessage);
|
|
}, onError: (error) {
|
|
_logger.severe('Error getting direct messages: $error', Trace.current());
|
|
});
|
|
|
|
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',
|
|
Trace.current(),
|
|
);
|
|
return;
|
|
}
|
|
|
|
await ref.read(markDirectMessageReadProvider(profile, m).future).match(
|
|
onSuccess: (updatedItem) {
|
|
final newState = state.deepCopy();
|
|
newState.messages[oldIndex] = updatedItem;
|
|
update(newState);
|
|
ref.read(notificationsManagerProvider(profile).notifier).refreshDms();
|
|
},
|
|
onError: (error) {
|
|
_logger.severe(
|
|
'Error getting direct messages: $error',
|
|
Trace.current(),
|
|
);
|
|
},
|
|
);
|
|
}
|
|
}
|