fix(#252): harden block gating per Gemini review

Guard _sendMessageDirect too (automatic retries route there without
passing sendMessage, so a pre-block message kept retrying post-block),
log both connector drops instead of returning silently, and surface a
blocked-contact snackbar on the manual retry and reaction paths.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
fix/252-block-outgoing-dm
Strycher 5 days ago
parent f90816c876
commit 47bc8d2fb4

@ -1235,6 +1235,15 @@ class MeshCoreConnector extends ChangeNotifier {
int timestampSeconds,
) async {
if (!isConnected || text.isEmpty) return;
// Automatic retries route here without passing sendMessage stop them
// too once the contact is blocked (#252).
if (_blockService?.isBlocked(contact.publicKeyHex) ?? false) {
appLogger.info(
'Dropped outgoing DM retry to blocked contact',
tag: 'Connector',
);
return;
}
try {
await _waitForRadioQuiet(lastInboundRxTime: _lastContactMsgRxTime);
final outboundText = prepareContactOutboundText(contact, text);
@ -3080,7 +3089,13 @@ class MeshCoreConnector extends ChangeNotifier {
if (!isConnected || text.isEmpty) return;
// Outgoing DMs (incl. reactions and retries) to a blocked contact are
// dropped mirrors the incoming DM-drop so a block is symmetric (#252).
if (_blockService?.isBlocked(contact.publicKeyHex) ?? false) return;
if (_blockService?.isBlocked(contact.publicKeyHex) ?? false) {
appLogger.info(
'Dropped outgoing DM to blocked contact',
tag: 'Connector',
);
return;
}
// Check if this is a reaction - apply locally with pending status and route through retry service
final reactionInfo = ReactionHelper.parseReaction(text);

@ -1789,6 +1789,13 @@ class _ChatScreenState extends State<ChatScreen> {
void _retryMessage(Message message) {
final connector = Provider.of<MeshCoreConnector>(context, listen: false);
if (context.read<BlockService>().isBlocked(widget.contact.publicKeyHex)) {
showDismissibleSnackBar(
context,
content: Text(context.l10n.block_composerNotice),
);
return;
}
// Retry using the contact's current path override setting
connector.sendMessage(_resolveContact(connector), message.text);
showDismissibleSnackBar(
@ -1811,6 +1818,13 @@ class _ChatScreenState extends State<ChatScreen> {
void _sendReaction(Message message, Contact senderContact, String emoji) {
final connector = context.read<MeshCoreConnector>();
if (context.read<BlockService>().isBlocked(widget.contact.publicKeyHex)) {
showDismissibleSnackBar(
context,
content: Text(context.l10n.block_composerNotice),
);
return;
}
final emojiIndex = ReactionHelper.emojiToIndex(emoji);
if (emojiIndex == null) return; // Unknown emoji, skip
final timestampSecs = message.timestamp.millisecondsSinceEpoch ~/ 1000;

Loading…
Cancel
Save

Powered by TurnKey Linux.