import "dart:typed_data"; import "package:auto_route/auto_route.dart"; import "package:flutter/material.dart"; import "package:flutter_riverpod/flutter_riverpod.dart"; import "package:smol_mail/data/providers/providers.dart"; import "package:smol_mail/presentation/widgets/image_banner.dart"; import "package:smol_mail/presentation/widgets/message/message_view.dart"; import "package:smol_mail/presentation/theme/app_colors.dart"; import "package:smol_mail/shared/utils/snackbar.dart"; import "package:smol_mail/smol/errors.dart"; /// Fetched mail is acknowledged off the server during fetch, so deleting here /// removes only the local sealed copy. @RoutePage() class MessageDetailScreen extends ConsumerWidget { final String folder; final String id; const MessageDetailScreen({ super.key, required this.folder, required this.id, }); Future _delete(BuildContext context, WidgetRef ref) async { await ref.read(storeProvider).deleteMessage(folder, id); ref.read(revisionProvider.notifier).bump(); if (context.mounted) { AutoRouter.of(context).pop(); } } Future _nameSender(BuildContext context, WidgetRef ref, Uint8List senderKey) async { final client = ref.read(clientProvider); final controller = TextEditingController(); final address = await showDialog( context: context, builder: (ctx) => AlertDialog( backgroundColor: Theme.of(context).extension()!.cardFill, content: TextField( controller: controller, decoration: InputDecoration( hintText: "user@host or smol://…", filled: true, fillColor: Theme.of(context).colorScheme.surface, ), ), actions: [ TextButton( onPressed: () => Navigator.of(ctx).pop(controller.text), child: const Text("Save"), ), ], ), ); if (address == null || address.trim().isEmpty) return; try { await client.nameSender(address, senderKey); ref.read(revisionProvider.notifier).bump(); if (context.mounted) { ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text("Address saved for this sender")), ); } } on SmolError catch (err) { if (context.mounted) { showErrorSnackBar(context, err.message); } } } @override Widget build(BuildContext context, WidgetRef ref) { final record = ref.watch(storeProvider).getMessage(folder, id); if (record == null) { return Scaffold( appBar: AppBar(), body: const ImageBanner( imgSrc: "assets/images/error.png", text: "Message not found!", ), ); } final client = ref.read(clientProvider); final opened = client.describe(record); final isSent = folder == "sent"; final who = isSent ? (record.recipient ?? "") : (opened.sender == null ? "" : ref.watch(storeProvider).addressForKey(opened.sender!) ?? ""); return Scaffold( appBar: AppBar( title: who.isEmpty ? null : Text( who, overflow: TextOverflow.ellipsis, style: TextStyle( fontFamily: "Inter", fontWeight: FontWeight.w500, fontSize: 18, color: Theme.of(context).colorScheme.onSurface, ), ), actions: [ IconButton( tooltip: "Delete local copy", onPressed: () => _delete(context, ref), icon: const Icon(Icons.delete), ), ], ), body: SingleChildScrollView( padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 10), child: MessageView( record: record, opened: opened, onNameSender: opened.sender == null ? null : (key) => _nameSender(context, ref, key), ), ), ); } }