feat(#262): 3-way notify selector on the Channels screen

The channel long-press sheet's binary Mute/Unmute tile becomes a
Notifications tile showing the current level, opening a picker with All
messages / Mentions only / Off.

The mode is read and written against the channel's PSK identity via
AppSettings.channelNotifyKey, so it survives a rename and does not follow a
reused slot (#259). Plain ListTiles with a check mark are used rather than
RadioListTile to stay clear of the Radio groupValue deprecation.

Adds channels_notifications / channels_notifyAll / channels_notifyMentionsOnly
/ channels_notifyOff to app_en.arb and regenerates l10n; the other 17 locales
fall back to English and are recorded in untranslated.json.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
pull/266/head
Strycher 5 days ago
parent ceed58373f
commit 4b05cccf5f

@ -556,6 +556,10 @@
"channels_editChannel": "Edit channel",
"channels_muteChannel": "Mute channel",
"channels_unmuteChannel": "Unmute channel",
"channels_notifications": "Notifications",
"channels_notifyAll": "All messages",
"channels_notifyMentionsOnly": "Mentions only",
"channels_notifyOff": "Off",
"channels_deleteChannel": "Delete channel",
"channels_deleteChannelConfirm": "Delete \"{name}\"? This cannot be undone.",
"@channels_deleteChannelConfirm": {

@ -2212,6 +2212,30 @@ abstract class AppLocalizations {
/// **'Unmute channel'**
String get channels_unmuteChannel;
/// No description provided for @channels_notifications.
///
/// In en, this message translates to:
/// **'Notifications'**
String get channels_notifications;
/// No description provided for @channels_notifyAll.
///
/// In en, this message translates to:
/// **'All messages'**
String get channels_notifyAll;
/// No description provided for @channels_notifyMentionsOnly.
///
/// In en, this message translates to:
/// **'Mentions only'**
String get channels_notifyMentionsOnly;
/// No description provided for @channels_notifyOff.
///
/// In en, this message translates to:
/// **'Off'**
String get channels_notifyOff;
/// No description provided for @channels_deleteChannel.
///
/// In en, this message translates to:

@ -1186,6 +1186,18 @@ class AppLocalizationsBg extends AppLocalizations {
@override
String get channels_unmuteChannel => 'Включи известията на канала';
@override
String get channels_notifications => 'Notifications';
@override
String get channels_notifyAll => 'All messages';
@override
String get channels_notifyMentionsOnly => 'Mentions only';
@override
String get channels_notifyOff => 'Off';
@override
String get channels_deleteChannel => 'Изтрий канала';

@ -1181,6 +1181,18 @@ class AppLocalizationsDe extends AppLocalizations {
@override
String get channels_unmuteChannel => 'Kanal Stummschaltung aufheben';
@override
String get channels_notifications => 'Notifications';
@override
String get channels_notifyAll => 'All messages';
@override
String get channels_notifyMentionsOnly => 'Mentions only';
@override
String get channels_notifyOff => 'Off';
@override
String get channels_deleteChannel => 'Lösche den Kanal';

@ -1162,6 +1162,18 @@ class AppLocalizationsEn extends AppLocalizations {
@override
String get channels_unmuteChannel => 'Unmute channel';
@override
String get channels_notifications => 'Notifications';
@override
String get channels_notifyAll => 'All messages';
@override
String get channels_notifyMentionsOnly => 'Mentions only';
@override
String get channels_notifyOff => 'Off';
@override
String get channels_deleteChannel => 'Delete channel';

@ -1182,6 +1182,18 @@ class AppLocalizationsEs extends AppLocalizations {
@override
String get channels_unmuteChannel => 'Activar canal';
@override
String get channels_notifications => 'Notifications';
@override
String get channels_notifyAll => 'All messages';
@override
String get channels_notifyMentionsOnly => 'Mentions only';
@override
String get channels_notifyOff => 'Off';
@override
String get channels_deleteChannel => 'Eliminar canal';

@ -1187,6 +1187,18 @@ class AppLocalizationsFr extends AppLocalizations {
@override
String get channels_unmuteChannel => 'Réactiver les notifications du canal';
@override
String get channels_notifications => 'Notifications';
@override
String get channels_notifyAll => 'All messages';
@override
String get channels_notifyMentionsOnly => 'Mentions only';
@override
String get channels_notifyOff => 'Off';
@override
String get channels_deleteChannel => 'Supprimer le canal';

@ -1187,6 +1187,18 @@ class AppLocalizationsHu extends AppLocalizations {
@override
String get channels_unmuteChannel => 'Engedje be a hangot';
@override
String get channels_notifications => 'Notifications';
@override
String get channels_notifyAll => 'All messages';
@override
String get channels_notifyMentionsOnly => 'Mentions only';
@override
String get channels_notifyOff => 'Off';
@override
String get channels_deleteChannel => 'Mozdony törlése';

@ -1183,6 +1183,18 @@ class AppLocalizationsIt extends AppLocalizations {
@override
String get channels_unmuteChannel => 'Attiva notifiche canale';
@override
String get channels_notifications => 'Notifications';
@override
String get channels_notifyAll => 'All messages';
@override
String get channels_notifyMentionsOnly => 'Mentions only';
@override
String get channels_notifyOff => 'Off';
@override
String get channels_deleteChannel => 'Elimina canale';

@ -1130,6 +1130,18 @@ class AppLocalizationsJa extends AppLocalizations {
@override
String get channels_unmuteChannel => 'ミュートを解除する';
@override
String get channels_notifications => 'Notifications';
@override
String get channels_notifyAll => 'All messages';
@override
String get channels_notifyMentionsOnly => 'Mentions only';
@override
String get channels_notifyOff => 'Off';
@override
String get channels_deleteChannel => 'チャンネルを削除する';

@ -1125,6 +1125,18 @@ class AppLocalizationsKo extends AppLocalizations {
@override
String get channels_unmuteChannel => '채널 음소거 해제';
@override
String get channels_notifications => 'Notifications';
@override
String get channels_notifyAll => 'All messages';
@override
String get channels_notifyMentionsOnly => 'Mentions only';
@override
String get channels_notifyOff => 'Off';
@override
String get channels_deleteChannel => '채널 삭제';

@ -1173,6 +1173,18 @@ class AppLocalizationsNl extends AppLocalizations {
@override
String get channels_unmuteChannel => 'Kanaal dempen opheffen';
@override
String get channels_notifications => 'Notifications';
@override
String get channels_notifyAll => 'All messages';
@override
String get channels_notifyMentionsOnly => 'Mentions only';
@override
String get channels_notifyOff => 'Off';
@override
String get channels_deleteChannel => 'Kanaal verwijderen';

@ -1193,6 +1193,18 @@ class AppLocalizationsPl extends AppLocalizations {
@override
String get channels_unmuteChannel => 'Wyłącz wyciszenie kanału';
@override
String get channels_notifications => 'Notifications';
@override
String get channels_notifyAll => 'All messages';
@override
String get channels_notifyMentionsOnly => 'Mentions only';
@override
String get channels_notifyOff => 'Off';
@override
String get channels_deleteChannel => 'Usuń kanał';

@ -1183,6 +1183,18 @@ class AppLocalizationsPt extends AppLocalizations {
@override
String get channels_unmuteChannel => 'Ativar canal';
@override
String get channels_notifications => 'Notifications';
@override
String get channels_notifyAll => 'All messages';
@override
String get channels_notifyMentionsOnly => 'Mentions only';
@override
String get channels_notifyOff => 'Off';
@override
String get channels_deleteChannel => 'Excluir canal';

@ -1184,6 +1184,18 @@ class AppLocalizationsRu extends AppLocalizations {
@override
String get channels_unmuteChannel => 'Включить уведомления канала';
@override
String get channels_notifications => 'Notifications';
@override
String get channels_notifyAll => 'All messages';
@override
String get channels_notifyMentionsOnly => 'Mentions only';
@override
String get channels_notifyOff => 'Off';
@override
String get channels_deleteChannel => 'Удалить канал';

@ -1173,6 +1173,18 @@ class AppLocalizationsSk extends AppLocalizations {
@override
String get channels_unmuteChannel => 'Zrušiť stlmenie kanála';
@override
String get channels_notifications => 'Notifications';
@override
String get channels_notifyAll => 'All messages';
@override
String get channels_notifyMentionsOnly => 'Mentions only';
@override
String get channels_notifyOff => 'Off';
@override
String get channels_deleteChannel => 'Odstrániť kanál';

@ -1170,6 +1170,18 @@ class AppLocalizationsSl extends AppLocalizations {
@override
String get channels_unmuteChannel => 'Vklopi obvestila kanala';
@override
String get channels_notifications => 'Notifications';
@override
String get channels_notifyAll => 'All messages';
@override
String get channels_notifyMentionsOnly => 'Mentions only';
@override
String get channels_notifyOff => 'Off';
@override
String get channels_deleteChannel => 'Pošlji kanal';

@ -1164,6 +1164,18 @@ class AppLocalizationsSv extends AppLocalizations {
@override
String get channels_unmuteChannel => 'Slå på ljud för kanal';
@override
String get channels_notifications => 'Notifications';
@override
String get channels_notifyAll => 'All messages';
@override
String get channels_notifyMentionsOnly => 'Mentions only';
@override
String get channels_notifyOff => 'Off';
@override
String get channels_deleteChannel => 'Ta bort kanal';

@ -1179,6 +1179,18 @@ class AppLocalizationsUk extends AppLocalizations {
@override
String get channels_unmuteChannel => 'Увімкнути сповіщення каналу';
@override
String get channels_notifications => 'Notifications';
@override
String get channels_notifyAll => 'All messages';
@override
String get channels_notifyMentionsOnly => 'Mentions only';
@override
String get channels_notifyOff => 'Off';
@override
String get channels_deleteChannel => 'Видалити канал';

@ -1111,6 +1111,18 @@ class AppLocalizationsZh extends AppLocalizations {
@override
String get channels_unmuteChannel => '取消静音频道';
@override
String get channels_notifications => 'Notifications';
@override
String get channels_notifyAll => 'All messages';
@override
String get channels_notifyMentionsOnly => 'Mentions only';
@override
String get channels_notifyOff => 'Off';
@override
String get channels_deleteChannel => '删除频道';

@ -13,6 +13,7 @@ import '../connector/meshcore_connector.dart';
import '../l10n/l10n.dart';
import '../services/app_settings_service.dart';
import '../services/ui_view_state_service.dart';
import '../models/app_settings.dart';
import '../models/channel.dart';
import '../models/community.dart';
import '../storage/community_store.dart';
@ -492,6 +493,71 @@ class _ChannelsScreenState extends State<ChannelsScreen>
);
}
/// Notify-mode storage key for [channel]: its PSK identity, so the setting
/// survives a rename and does not follow a reused slot (#259).
String _notifyKeyFor(Channel channel) => AppSettings.channelNotifyKey(
channelIndex: channel.index,
pskHex: channel.pskHex,
);
IconData _notifyModeIcon(ChannelNotifyMode mode) {
switch (mode) {
case ChannelNotifyMode.all:
return Icons.notifications_outlined;
case ChannelNotifyMode.mentionsOnly:
return Icons.alternate_email;
case ChannelNotifyMode.off:
return Icons.notifications_off_outlined;
}
}
String _notifyModeLabel(BuildContext context, ChannelNotifyMode mode) {
switch (mode) {
case ChannelNotifyMode.all:
return context.l10n.channels_notifyAll;
case ChannelNotifyMode.mentionsOnly:
return context.l10n.channels_notifyMentionsOnly;
case ChannelNotifyMode.off:
return context.l10n.channels_notifyOff;
}
}
void _showNotifyModeDialog(BuildContext context, Channel channel) {
final settingsService = context.read<AppSettingsService>();
final identityKey = _notifyKeyFor(channel);
final current = settingsService.channelNotifyMode(
identityKey: identityKey,
channelName: channel.name,
);
showDialog<void>(
context: context,
builder: (dialogContext) => AlertDialog(
title: Text(dialogContext.l10n.channels_notifications),
contentPadding: const EdgeInsets.symmetric(vertical: 8),
content: Column(
mainAxisSize: MainAxisSize.min,
children: [
for (final mode in ChannelNotifyMode.values)
ListTile(
leading: Icon(_notifyModeIcon(mode)),
title: Text(_notifyModeLabel(dialogContext, mode)),
trailing: mode == current ? const Icon(Icons.check) : null,
onTap: () async {
Navigator.pop(dialogContext);
await settingsService.setChannelNotifyMode(
identityKey: identityKey,
channelName: channel.name,
mode: mode,
);
},
),
],
),
),
);
}
void _showChannelActions(
BuildContext context,
MeshCoreConnector connector,
@ -500,7 +566,10 @@ class _ChannelsScreenState extends State<ChannelsScreen>
) {
final parentContext = context;
final settingsService = context.read<AppSettingsService>();
final isMuted = settingsService.isChannelMuted(channel.name);
final notifyMode = settingsService.channelNotifyMode(
identityKey: _notifyKeyFor(channel),
channelName: channel.name,
);
showModalBottomSheet(
context: parentContext,
@ -531,22 +600,14 @@ class _ChannelsScreenState extends State<ChannelsScreen>
},
),
ListTile(
leading: Icon(
isMuted
? Icons.notifications_outlined
: Icons.notifications_off_outlined,
),
title: Text(
isMuted
? context.l10n.channels_unmuteChannel
: context.l10n.channels_muteChannel,
),
leading: Icon(_notifyModeIcon(notifyMode)),
title: Text(context.l10n.channels_notifications),
subtitle: Text(_notifyModeLabel(context, notifyMode)),
onTap: () async {
Navigator.pop(sheetContext);
if (isMuted) {
await settingsService.unmuteChannel(channel.name);
} else {
await settingsService.muteChannel(channel.name);
await Future.delayed(const Duration(milliseconds: 100));
if (parentContext.mounted) {
_showNotifyModeDialog(parentContext, channel);
}
},
),

@ -19,6 +19,10 @@
"appSettings_clockSystem",
"appSettings_clock12h",
"appSettings_clock24h",
"channels_notifications",
"channels_notifyAll",
"channels_notifyMentionsOnly",
"channels_notifyOff",
"chat_replyWithRoute",
"channel_heardTooltip",
"path_suggestedRoute",
@ -73,6 +77,10 @@
"appSettings_clockSystem",
"appSettings_clock12h",
"appSettings_clock24h",
"channels_notifications",
"channels_notifyAll",
"channels_notifyMentionsOnly",
"channels_notifyOff",
"chat_replyWithRoute",
"channel_heardTooltip",
"path_suggestedRoute",
@ -127,6 +135,10 @@
"appSettings_clockSystem",
"appSettings_clock12h",
"appSettings_clock24h",
"channels_notifications",
"channels_notifyAll",
"channels_notifyMentionsOnly",
"channels_notifyOff",
"chat_replyWithRoute",
"channel_heardTooltip",
"path_suggestedRoute",
@ -181,6 +193,10 @@
"appSettings_clockSystem",
"appSettings_clock12h",
"appSettings_clock24h",
"channels_notifications",
"channels_notifyAll",
"channels_notifyMentionsOnly",
"channels_notifyOff",
"chat_replyWithRoute",
"channel_heardTooltip",
"path_suggestedRoute",
@ -235,6 +251,10 @@
"appSettings_clockSystem",
"appSettings_clock12h",
"appSettings_clock24h",
"channels_notifications",
"channels_notifyAll",
"channels_notifyMentionsOnly",
"channels_notifyOff",
"chat_replyWithRoute",
"channel_heardTooltip",
"path_suggestedRoute",
@ -289,6 +309,10 @@
"appSettings_clockSystem",
"appSettings_clock12h",
"appSettings_clock24h",
"channels_notifications",
"channels_notifyAll",
"channels_notifyMentionsOnly",
"channels_notifyOff",
"chat_replyWithRoute",
"channel_heardTooltip",
"path_suggestedRoute",
@ -343,6 +367,10 @@
"appSettings_clockSystem",
"appSettings_clock12h",
"appSettings_clock24h",
"channels_notifications",
"channels_notifyAll",
"channels_notifyMentionsOnly",
"channels_notifyOff",
"chat_replyWithRoute",
"channel_heardTooltip",
"path_suggestedRoute",
@ -397,6 +425,10 @@
"appSettings_clockSystem",
"appSettings_clock12h",
"appSettings_clock24h",
"channels_notifications",
"channels_notifyAll",
"channels_notifyMentionsOnly",
"channels_notifyOff",
"chat_replyWithRoute",
"channel_heardTooltip",
"path_suggestedRoute",
@ -451,6 +483,10 @@
"appSettings_clockSystem",
"appSettings_clock12h",
"appSettings_clock24h",
"channels_notifications",
"channels_notifyAll",
"channels_notifyMentionsOnly",
"channels_notifyOff",
"chat_replyWithRoute",
"channel_heardTooltip",
"path_suggestedRoute",
@ -505,6 +541,10 @@
"appSettings_clockSystem",
"appSettings_clock12h",
"appSettings_clock24h",
"channels_notifications",
"channels_notifyAll",
"channels_notifyMentionsOnly",
"channels_notifyOff",
"chat_replyWithRoute",
"channel_heardTooltip",
"path_suggestedRoute",
@ -559,6 +599,10 @@
"appSettings_clockSystem",
"appSettings_clock12h",
"appSettings_clock24h",
"channels_notifications",
"channels_notifyAll",
"channels_notifyMentionsOnly",
"channels_notifyOff",
"chat_replyWithRoute",
"channel_heardTooltip",
"path_suggestedRoute",
@ -613,6 +657,10 @@
"appSettings_clockSystem",
"appSettings_clock12h",
"appSettings_clock24h",
"channels_notifications",
"channels_notifyAll",
"channels_notifyMentionsOnly",
"channels_notifyOff",
"chat_replyWithRoute",
"channel_heardTooltip",
"path_suggestedRoute",
@ -667,6 +715,10 @@
"appSettings_clockSystem",
"appSettings_clock12h",
"appSettings_clock24h",
"channels_notifications",
"channels_notifyAll",
"channels_notifyMentionsOnly",
"channels_notifyOff",
"chat_replyWithRoute",
"channel_heardTooltip",
"path_suggestedRoute",
@ -721,6 +773,10 @@
"appSettings_clockSystem",
"appSettings_clock12h",
"appSettings_clock24h",
"channels_notifications",
"channels_notifyAll",
"channels_notifyMentionsOnly",
"channels_notifyOff",
"chat_replyWithRoute",
"channel_heardTooltip",
"path_suggestedRoute",
@ -775,6 +831,10 @@
"appSettings_clockSystem",
"appSettings_clock12h",
"appSettings_clock24h",
"channels_notifications",
"channels_notifyAll",
"channels_notifyMentionsOnly",
"channels_notifyOff",
"chat_replyWithRoute",
"channel_heardTooltip",
"path_suggestedRoute",
@ -829,6 +889,10 @@
"appSettings_clockSystem",
"appSettings_clock12h",
"appSettings_clock24h",
"channels_notifications",
"channels_notifyAll",
"channels_notifyMentionsOnly",
"channels_notifyOff",
"chat_replyWithRoute",
"channel_heardTooltip",
"path_suggestedRoute",
@ -883,6 +947,10 @@
"appSettings_clockSystem",
"appSettings_clock12h",
"appSettings_clock24h",
"channels_notifications",
"channels_notifyAll",
"channels_notifyMentionsOnly",
"channels_notifyOff",
"chat_replyWithRoute",
"channel_heardTooltip",
"path_suggestedRoute",

Loading…
Cancel
Save

Powered by TurnKey Linux.