From 52efa03d325c047866d40990ecfde7d62a1d08ad Mon Sep 17 00:00:00 2001 From: Janez T Date: Wed, 15 Oct 2025 15:04:09 +0200 Subject: [PATCH] feat: Add message deletion functionality with confirmation dialog and options --- lib/providers/messages_provider.dart | 31 ++++++++++++ lib/screens/messages_tab.dart | 74 ++++++++++++++++++++++++++++ 2 files changed, 105 insertions(+) diff --git a/lib/providers/messages_provider.dart b/lib/providers/messages_provider.dart index 0ff0384..dcda8a8 100644 --- a/lib/providers/messages_provider.dart +++ b/lib/providers/messages_provider.dart @@ -284,6 +284,37 @@ class MessagesProvider with ChangeNotifier { notifyListeners(); } + /// Delete a specific message by ID + void deleteMessage(String messageId) { + final index = _messages.indexWhere((m) => m.id == messageId); + if (index != -1) { + final message = _messages[index]; + + // If it's a SAR marker message, also remove the marker + if (message.isSarMarker) { + final marker = message.toSarMarker(); + if (marker != null) { + _sarMarkers.remove(marker.id); + } + } + + // Remove from messages list + _messages.removeAt(index); + + // Cancel timeout timer if it exists + if (message.expectedAckTag != null) { + _timeoutTimers[message.expectedAckTag]?.cancel(); + _timeoutTimers.remove(message.expectedAckTag); + _pendingSentMessages.remove(message.expectedAckTag); + } + + print('🗑️ [MessagesProvider] Message $messageId deleted'); + + _persistMessages(); + notifyListeners(); + } + } + /// Clear all messages void clearMessages() { _messages.clear(); diff --git a/lib/screens/messages_tab.dart b/lib/screens/messages_tab.dart index 6ba828e..8ad8f24 100644 --- a/lib/screens/messages_tab.dart +++ b/lib/screens/messages_tab.dart @@ -498,6 +498,79 @@ class _MessageBubble extends StatelessWidget { } } + void _showMessageOptions(BuildContext context) { + showModalBottomSheet( + context: context, + backgroundColor: Theme.of(context).colorScheme.surface, + shape: const RoundedRectangleBorder( + borderRadius: BorderRadius.vertical(top: Radius.circular(16)), + ), + builder: (context) => Padding( + padding: const EdgeInsets.symmetric(vertical: 16), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + // Copy text option + ListTile( + leading: const Icon(Icons.copy), + title: const Text('Copy text'), + onTap: () { + Clipboard.setData(ClipboardData(text: message.text)); + Navigator.pop(context); + ScaffoldMessenger.of(context).showSnackBar( + const SnackBar( + content: Text('Text copied to clipboard'), + duration: Duration(seconds: 1), + ), + ); + }, + ), + // Delete message option + ListTile( + leading: const Icon(Icons.delete, color: Colors.red), + title: const Text('Delete message', style: TextStyle(color: Colors.red)), + onTap: () { + Navigator.pop(context); + _showDeleteConfirmation(context); + }, + ), + ], + ), + ), + ); + } + + void _showDeleteConfirmation(BuildContext context) { + showDialog( + context: context, + builder: (context) => AlertDialog( + title: const Text('Delete message'), + content: const Text('Are you sure you want to delete this message?'), + actions: [ + TextButton( + onPressed: () => Navigator.pop(context), + child: const Text('Cancel'), + ), + TextButton( + onPressed: () { + final messagesProvider = context.read(); + messagesProvider.deleteMessage(message.id); + Navigator.pop(context); + ScaffoldMessenger.of(context).showSnackBar( + const SnackBar( + content: Text('Message deleted'), + duration: Duration(seconds: 1), + ), + ); + }, + style: TextButton.styleFrom(foregroundColor: Colors.red), + child: const Text('Delete'), + ), + ], + ), + ); + } + @override Widget build(BuildContext context) { final isSarMarker = message.isSarMarker; @@ -518,6 +591,7 @@ class _MessageBubble extends StatelessWidget { return GestureDetector( onTap: onTap, + onLongPress: () => _showMessageOptions(context), child: Container( margin: const EdgeInsets.only(bottom: 12), padding: const EdgeInsets.all(16),