Add initial DM "mark read" implementation

codemagic-setup
Hank Grabowski 2023-01-25 11:26:29 -06:00
rodzic 0b1b819aff
commit bdb01e5f26
7 zmienionych plików z 101 dodań i 7 usunięć

Wyświetl plik

@ -532,6 +532,19 @@ class FriendicaClient {
.execErrorCast();
}
FutureResult<DirectMessage, ExecError> markDirectMessageRead(
DirectMessage message) async {
final id = message.id;
final url = Uri.parse(
'https://$serverName/api/friendica/direct_messages_setseen?id=$id');
final result =
await _postUrl(url, {}).andThenSuccessAsync((jsonString) async {
return message.copy(seen: true);
});
return result.execErrorCast();
}
FutureResult<PagedResponse<String>, ExecError> _getUrl(Uri url) async {
_logger.finer('GET: $url');
try {

Wyświetl plik

@ -32,6 +32,31 @@ class DirectMessage {
required this.parentUri,
});
DirectMessage copy({
String? id,
String? senderId,
String? senderScreenName,
String? recipientId,
String? recipientScreenName,
String? title,
String? text,
int? createdAt,
bool? seen,
String? parentUri,
}) =>
DirectMessage(
id: id ?? this.id,
senderId: senderId ?? this.senderId,
senderScreenName: senderScreenName ?? this.senderScreenName,
recipientId: recipientId ?? this.recipientId,
recipientScreenName: recipientScreenName ?? this.recipientScreenName,
title: title ?? this.title,
text: text ?? this.text,
createdAt: createdAt ?? this.createdAt,
seen: seen ?? this.seen,
parentUri: parentUri ?? this.parentUri,
);
@override
bool operator ==(Object other) =>
identical(this, other) ||

Wyświetl plik

@ -19,6 +19,12 @@ class DirectMessageThread {
required this.parentUri,
});
get allSeen => messages.isEmpty
? false
: messages
.map((m) => m.seen)
.reduce((allUnseen, thisUnseen) => allUnseen && thisUnseen);
static List<DirectMessageThread> createThreads(
Iterable<DirectMessage> messages) {
final cm = getIt<ConnectionsManager>();

Wyświetl plik

@ -27,11 +27,14 @@ class MessageThreadScreen extends StatelessWidget {
onError: (_) => 'Thread');
return Scaffold(
appBar: StandardAppBar.build(context, title),
body: buildBody(result),
body: buildBody(result, service),
);
}
Widget buildBody(Result<DirectMessageThread, ExecError> result) {
Widget buildBody(
Result<DirectMessageThread, ExecError> result,
DirectMessageService service,
) {
return result.fold(
onSuccess: (thread) {
final yourId = getIt<AuthService>().currentId;
@ -49,13 +52,21 @@ class MessageThreadScreen extends StatelessWidget {
? yourAvatarUrl
: participants[m.senderId]?.avatarUrl ?? '';
return ListTile(
onTap: m.seen
? null
: () => service.markMessageRead(parentThreadId, m),
leading: ImageControl(
imageUrl: imageUrl,
iconOverride: const Icon(Icons.person),
width: 32.0,
onTap: null,
),
title: Text(text),
title: Text(
text,
style: m.seen
? null
: TextStyle(fontWeight: FontWeight.bold),
),
trailing: Text(
DateTime.fromMillisecondsSinceEpoch(m.createdAt * 1000)
.toString()),

Wyświetl plik

@ -31,6 +31,9 @@ class MessagesScreen extends StatelessWidget {
itemCount: threads.length,
itemBuilder: (context, index) {
final thread = threads[index];
final style = thread.allSeen
? null
: TextStyle(fontWeight: FontWeight.bold);
return ListTile(
onTap: () => context.pushNamed(
ScreenPaths.thread,
@ -48,10 +51,17 @@ class MessagesScreen extends StatelessWidget {
...thread.participants.map((p) => '${p.name}(${p.handle})')
].join(thread.participants.length == 1 ? ' & ' : ', '),
softWrap: true,
style: style,
),
subtitle: Text(
thread.title,
style: style,
),
trailing: Text(
ElapsedDateUtils.epochSecondsToString(
thread.messages.first.createdAt),
style: style,
),
subtitle: Text(thread.title),
trailing: Text(ElapsedDateUtils.epochSecondsToString(
thread.messages.first.createdAt)),
);
},
separatorBuilder: (_, __) => const Divider(),

Wyświetl plik

@ -36,7 +36,7 @@ extension DirectMessageFriendicaExtension on DirectMessage {
})
: 0;
final bool seen = json['friendica_seen'] == 'true';
final bool seen = json['friendica_seen'];
final String parentUri = json['friendica_parent_uri'];

Wyświetl plik

@ -4,6 +4,7 @@ import 'package:result_monad/result_monad.dart';
import '../friendica_client/paging_data.dart';
import '../globals.dart';
import '../models/direct_message.dart';
import '../models/direct_message_thread.dart';
import '../models/exec_error.dart';
import 'auth_service.dart';
@ -52,4 +53,32 @@ class DirectMessageService extends ChangeNotifier {
notifyListeners();
}
Future<void> markMessageRead(String threadId, DirectMessage m) async {
final thread = _threads[threadId];
if (thread == null) {
_logger.severe('Message is not for this thread: $threadId, $m');
return;
}
final oldIndex = thread.messages.indexOf(m);
if (oldIndex < 0) {
_logger.severe('Message is not for this thread: $threadId, $m');
return;
}
await getIt<AuthService>()
.currentClient
.andThenAsync((client) => client.markDirectMessageRead(m))
.match(
onSuccess: (update) {
thread.messages.removeAt(oldIndex);
thread.messages.insert(oldIndex, update);
notifyListeners();
},
onError: (error) {
_logger.severe('Error getting direct messages: $error');
},
);
notifyListeners();
}
}