relatica/lib/screens/message_thread_screen.dart

84 lines
2.9 KiB
Dart
Raw Normal View History

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),
body: buildBody(result, service),
);
}
Widget buildBody(
Result<DirectMessageThread, ExecError> result,
DirectMessageService service,
) {
return result.fold(
onSuccess: (thread) {
final yourId = getIt<AuthService>().currentId;
final yourAvatarUrl = getIt<AuthService>().currentAvatarUrl;
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];
final imageUrl = m.senderId == yourId
? 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,
style: m.seen
? null
: TextStyle(fontWeight: FontWeight.bold),
),
trailing: Text(
DateTime.fromMillisecondsSinceEpoch(m.createdAt * 1000)
.toString()),
);
},
separatorBuilder: (_, __) => const Divider(),
itemCount: thread.messages.length));
},
onError: (error) => Center(
child: Text('Error getting thread: $error'),
),
);
}
}