2023-01-25 01:53:55 +00:00
|
|
|
import 'package:flutter/material.dart';
|
|
|
|
import 'package:provider/provider.dart';
|
|
|
|
import 'package:result_monad/result_monad.dart';
|
|
|
|
|
|
|
|
import '../controls/image_control.dart';
|
|
|
|
import '../controls/standard_appbar.dart';
|
|
|
|
import '../globals.dart';
|
|
|
|
import '../models/direct_message_thread.dart';
|
|
|
|
import '../models/exec_error.dart';
|
|
|
|
import '../services/auth_service.dart';
|
|
|
|
import '../services/direct_message_service.dart';
|
|
|
|
|
|
|
|
class MessageThreadScreen extends StatelessWidget {
|
|
|
|
final String parentThreadId;
|
|
|
|
|
|
|
|
const MessageThreadScreen({
|
|
|
|
super.key,
|
|
|
|
required this.parentThreadId,
|
|
|
|
});
|
|
|
|
|
|
|
|
@override
|
|
|
|
Widget build(BuildContext context) {
|
|
|
|
final service = context.watch<DirectMessageService>();
|
|
|
|
final result = service.getThreadByParentUri(parentThreadId);
|
|
|
|
final title = result.fold(
|
|
|
|
onSuccess: (t) => t.title.isEmpty ? 'Thread' : t.title,
|
|
|
|
onError: (_) => 'Thread');
|
|
|
|
return Scaffold(
|
|
|
|
appBar: StandardAppBar.build(context, title),
|
2023-01-25 17:26:29 +00:00
|
|
|
body: buildBody(result, service),
|
2023-01-25 01:53:55 +00:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2023-01-25 17:26:29 +00:00
|
|
|
Widget buildBody(
|
|
|
|
Result<DirectMessageThread, ExecError> result,
|
|
|
|
DirectMessageService service,
|
|
|
|
) {
|
2023-01-25 01:53:55 +00:00
|
|
|
return result.fold(
|
|
|
|
onSuccess: (thread) {
|
|
|
|
final yourId = getIt<AuthService>().currentId;
|
2023-01-25 12:41:41 +00:00
|
|
|
final yourAvatarUrl = getIt<AuthService>().currentAvatarUrl;
|
2023-01-25 01:53:55 +00:00
|
|
|
final participants =
|
|
|
|
Map.fromEntries(thread.participants.map((p) => MapEntry(p.id, p)));
|
|
|
|
return Center(
|
|
|
|
child: ListView.separated(
|
|
|
|
itemBuilder: (context, index) {
|
|
|
|
final m = thread.messages[index];
|
|
|
|
final textPieces = m.text.split('...\n');
|
|
|
|
final text =
|
|
|
|
textPieces.length == 1 ? textPieces[0] : textPieces[1];
|
2023-01-25 12:41:41 +00:00
|
|
|
final imageUrl = m.senderId == yourId
|
|
|
|
? yourAvatarUrl
|
|
|
|
: participants[m.senderId]?.avatarUrl ?? '';
|
2023-01-25 01:53:55 +00:00
|
|
|
return ListTile(
|
2023-01-25 17:26:29 +00:00
|
|
|
onTap: m.seen
|
|
|
|
? null
|
|
|
|
: () => service.markMessageRead(parentThreadId, m),
|
2023-01-25 12:41:41 +00:00
|
|
|
leading: ImageControl(
|
|
|
|
imageUrl: imageUrl,
|
|
|
|
iconOverride: const Icon(Icons.person),
|
|
|
|
width: 32.0,
|
|
|
|
onTap: null,
|
|
|
|
),
|
2023-01-25 17:26:29 +00:00
|
|
|
title: Text(
|
|
|
|
text,
|
|
|
|
style: m.seen
|
|
|
|
? null
|
|
|
|
: TextStyle(fontWeight: FontWeight.bold),
|
|
|
|
),
|
2023-01-25 01:53:55 +00:00
|
|
|
trailing: Text(
|
|
|
|
DateTime.fromMillisecondsSinceEpoch(m.createdAt * 1000)
|
|
|
|
.toString()),
|
|
|
|
);
|
|
|
|
},
|
|
|
|
separatorBuilder: (_, __) => const Divider(),
|
|
|
|
itemCount: thread.messages.length));
|
|
|
|
},
|
|
|
|
onError: (error) => Center(
|
|
|
|
child: Text('Error getting thread: $error'),
|
|
|
|
),
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|