fix(#565): surface add-contact failures instead of a dead tap

Gemini pre-PR review finding. importDiscoveredContact no-ops when the radio
is gone, and sendFrame throws on a mid-write disconnect or an unwritable BLE
characteristic. Both reached the user as a tap that appeared to work.

Checks the connection first, catches the write failure, logs it, and shows a
persistent error snackbar in either case (SAFELANE section 6: no silent
failures).
pull/585/head
Strycher 2 months ago
parent 22ce0f6338
commit d9bf2473ea

@ -912,6 +912,15 @@
}
}
},
"channel_senderAddNotConnected": "Not connected to a radio, so this sender can't be added yet",
"channel_senderAddFailed": "Couldn't add this sender: {error}",
"@channel_senderAddFailed": {
"placeholders": {
"error": {
"type": "String"
}
}
},
"channel_senderCandidate": "{keyPrefix} · {type}",
"@channel_senderCandidate": {
"placeholders": {

@ -3154,6 +3154,18 @@ abstract class AppLocalizations {
/// **'{count} nodes use this name'**
String channel_senderMultipleMatches(int count);
/// No description provided for @channel_senderAddNotConnected.
///
/// In en, this message translates to:
/// **'Not connected to a radio, so this sender can\'t be added yet'**
String get channel_senderAddNotConnected;
/// No description provided for @channel_senderAddFailed.
///
/// In en, this message translates to:
/// **'Couldn\'t add this sender: {error}'**
String channel_senderAddFailed(String error);
/// No description provided for @channel_senderCandidate.
///
/// In en, this message translates to:

@ -1756,6 +1756,15 @@ class AppLocalizationsBg extends AppLocalizations {
return '$count nodes use this name';
}
@override
String get channel_senderAddNotConnected =>
'Not connected to a radio, so this sender can\'t be added yet';
@override
String channel_senderAddFailed(String error) {
return 'Couldn\'t add this sender: $error';
}
@override
String channel_senderCandidate(String keyPrefix, String type) {
return '$keyPrefix · $type';

@ -1754,6 +1754,15 @@ class AppLocalizationsDe extends AppLocalizations {
return '$count nodes use this name';
}
@override
String get channel_senderAddNotConnected =>
'Not connected to a radio, so this sender can\'t be added yet';
@override
String channel_senderAddFailed(String error) {
return 'Couldn\'t add this sender: $error';
}
@override
String channel_senderCandidate(String keyPrefix, String type) {
return '$keyPrefix · $type';

@ -1725,6 +1725,15 @@ class AppLocalizationsEn extends AppLocalizations {
return '$count nodes use this name';
}
@override
String get channel_senderAddNotConnected =>
'Not connected to a radio, so this sender can\'t be added yet';
@override
String channel_senderAddFailed(String error) {
return 'Couldn\'t add this sender: $error';
}
@override
String channel_senderCandidate(String keyPrefix, String type) {
return '$keyPrefix · $type';

@ -1751,6 +1751,15 @@ class AppLocalizationsEs extends AppLocalizations {
return '$count nodes use this name';
}
@override
String get channel_senderAddNotConnected =>
'Not connected to a radio, so this sender can\'t be added yet';
@override
String channel_senderAddFailed(String error) {
return 'Couldn\'t add this sender: $error';
}
@override
String channel_senderCandidate(String keyPrefix, String type) {
return '$keyPrefix · $type';

@ -1758,6 +1758,15 @@ class AppLocalizationsFr extends AppLocalizations {
return '$count nodes use this name';
}
@override
String get channel_senderAddNotConnected =>
'Not connected to a radio, so this sender can\'t be added yet';
@override
String channel_senderAddFailed(String error) {
return 'Couldn\'t add this sender: $error';
}
@override
String channel_senderCandidate(String keyPrefix, String type) {
return '$keyPrefix · $type';

@ -1763,6 +1763,15 @@ class AppLocalizationsHu extends AppLocalizations {
return '$count nodes use this name';
}
@override
String get channel_senderAddNotConnected =>
'Not connected to a radio, so this sender can\'t be added yet';
@override
String channel_senderAddFailed(String error) {
return 'Couldn\'t add this sender: $error';
}
@override
String channel_senderCandidate(String keyPrefix, String type) {
return '$keyPrefix · $type';

@ -1753,6 +1753,15 @@ class AppLocalizationsIt extends AppLocalizations {
return '$count nodes use this name';
}
@override
String get channel_senderAddNotConnected =>
'Not connected to a radio, so this sender can\'t be added yet';
@override
String channel_senderAddFailed(String error) {
return 'Couldn\'t add this sender: $error';
}
@override
String channel_senderCandidate(String keyPrefix, String type) {
return '$keyPrefix · $type';

@ -1688,6 +1688,15 @@ class AppLocalizationsJa extends AppLocalizations {
return '$count nodes use this name';
}
@override
String get channel_senderAddNotConnected =>
'Not connected to a radio, so this sender can\'t be added yet';
@override
String channel_senderAddFailed(String error) {
return 'Couldn\'t add this sender: $error';
}
@override
String channel_senderCandidate(String keyPrefix, String type) {
return '$keyPrefix · $type';

@ -1684,6 +1684,15 @@ class AppLocalizationsKo extends AppLocalizations {
return '$count nodes use this name';
}
@override
String get channel_senderAddNotConnected =>
'Not connected to a radio, so this sender can\'t be added yet';
@override
String channel_senderAddFailed(String error) {
return 'Couldn\'t add this sender: $error';
}
@override
String channel_senderCandidate(String keyPrefix, String type) {
return '$keyPrefix · $type';

@ -1741,6 +1741,15 @@ class AppLocalizationsNl extends AppLocalizations {
return '$count nodes use this name';
}
@override
String get channel_senderAddNotConnected =>
'Not connected to a radio, so this sender can\'t be added yet';
@override
String channel_senderAddFailed(String error) {
return 'Couldn\'t add this sender: $error';
}
@override
String channel_senderCandidate(String keyPrefix, String type) {
return '$keyPrefix · $type';

@ -1766,6 +1766,15 @@ class AppLocalizationsPl extends AppLocalizations {
return '$count nodes use this name';
}
@override
String get channel_senderAddNotConnected =>
'Not connected to a radio, so this sender can\'t be added yet';
@override
String channel_senderAddFailed(String error) {
return 'Couldn\'t add this sender: $error';
}
@override
String channel_senderCandidate(String keyPrefix, String type) {
return '$keyPrefix · $type';

@ -1750,6 +1750,15 @@ class AppLocalizationsPt extends AppLocalizations {
return '$count nodes use this name';
}
@override
String get channel_senderAddNotConnected =>
'Not connected to a radio, so this sender can\'t be added yet';
@override
String channel_senderAddFailed(String error) {
return 'Couldn\'t add this sender: $error';
}
@override
String channel_senderCandidate(String keyPrefix, String type) {
return '$keyPrefix · $type';

@ -1754,6 +1754,15 @@ class AppLocalizationsRu extends AppLocalizations {
return '$count nodes use this name';
}
@override
String get channel_senderAddNotConnected =>
'Not connected to a radio, so this sender can\'t be added yet';
@override
String channel_senderAddFailed(String error) {
return 'Couldn\'t add this sender: $error';
}
@override
String channel_senderCandidate(String keyPrefix, String type) {
return '$keyPrefix · $type';

@ -1743,6 +1743,15 @@ class AppLocalizationsSk extends AppLocalizations {
return '$count nodes use this name';
}
@override
String get channel_senderAddNotConnected =>
'Not connected to a radio, so this sender can\'t be added yet';
@override
String channel_senderAddFailed(String error) {
return 'Couldn\'t add this sender: $error';
}
@override
String channel_senderCandidate(String keyPrefix, String type) {
return '$keyPrefix · $type';

@ -1739,6 +1739,15 @@ class AppLocalizationsSl extends AppLocalizations {
return '$count nodes use this name';
}
@override
String get channel_senderAddNotConnected =>
'Not connected to a radio, so this sender can\'t be added yet';
@override
String channel_senderAddFailed(String error) {
return 'Couldn\'t add this sender: $error';
}
@override
String channel_senderCandidate(String keyPrefix, String type) {
return '$keyPrefix · $type';

@ -1734,6 +1734,15 @@ class AppLocalizationsSv extends AppLocalizations {
return '$count nodes use this name';
}
@override
String get channel_senderAddNotConnected =>
'Not connected to a radio, so this sender can\'t be added yet';
@override
String channel_senderAddFailed(String error) {
return 'Couldn\'t add this sender: $error';
}
@override
String channel_senderCandidate(String keyPrefix, String type) {
return '$keyPrefix · $type';

@ -1749,6 +1749,15 @@ class AppLocalizationsUk extends AppLocalizations {
return '$count nodes use this name';
}
@override
String get channel_senderAddNotConnected =>
'Not connected to a radio, so this sender can\'t be added yet';
@override
String channel_senderAddFailed(String error) {
return 'Couldn\'t add this sender: $error';
}
@override
String channel_senderCandidate(String keyPrefix, String type) {
return '$keyPrefix · $type';

@ -1663,6 +1663,15 @@ class AppLocalizationsZh extends AppLocalizations {
return '$count nodes use this name';
}
@override
String get channel_senderAddNotConnected =>
'Not connected to a radio, so this sender can\'t be added yet';
@override
String channel_senderAddFailed(String error) {
return 'Couldn\'t add this sender: $error';
}
@override
String channel_senderCandidate(String keyPrefix, String type) {
return '$keyPrefix · $type';

@ -11,6 +11,7 @@ import 'package:provider/provider.dart';
import '../connector/meshcore_connector.dart';
import '../models/community.dart';
import '../storage/community_store.dart';
import '../utils/app_logger.dart';
import '../utils/platform_info.dart';
import '../helpers/chat_scroll_controller.dart';
import '../connector/meshcore_protocol.dart';
@ -797,12 +798,35 @@ class _ChannelChatScreenState extends State<ChannelChatScreen> {
Future<void> _addSenderContact(Contact candidate) async {
final connector = context.read<MeshCoreConnector>();
final messenger = ScaffoldMessenger.of(context);
final l10n = context.l10n;
await connector.importDiscoveredContact(candidate);
// importDiscoveredContact silently no-ops without a radio, and sendFrame
// throws on a mid-write disconnect. Neither may reach the user as a tap
// that just did nothing (#565).
if (!connector.isConnected) {
_showSenderError(l10n.channel_senderAddNotConnected);
return;
}
try {
await connector.importDiscoveredContact(candidate);
} catch (e) {
appLogger.error('Adding channel sender ${candidate.name} failed: $e');
if (!mounted) return;
_showSenderError(l10n.channel_senderAddFailed(e.toString()));
return;
}
if (!mounted) return;
messenger.showSnackBar(
SnackBar(content: Text(l10n.discoveredContacts_contactAdded)),
showDismissibleSnackBar(
context,
content: Text(l10n.discoveredContacts_contactAdded),
);
}
void _showSenderError(String message) {
showDismissibleSnackBar(
context,
content: Text(message),
backgroundColor: Theme.of(context).colorScheme.error,
persist: true,
);
}

Loading…
Cancel
Save

Powered by TurnKey Linux.