From 0330a952f29bdbffa90a77f90962de8df12ea724 Mon Sep 17 00:00:00 2001 From: SputNikPlop <100245448+SputNikPlop@users.noreply.github.com> Date: Sat, 24 May 2025 23:38:32 -0700 Subject: [PATCH 1/2] fix: cleanup sidebar --- lib/components/drawer/sidebar.dart | 201 ++++++++++++++------------ lib/l10n/app_en.arb | 5 + lib/models/quick_links.dart | 39 +++++ lib/screens/settings/quick_links.dart | 39 +++++ 4 files changed, 192 insertions(+), 92 deletions(-) diff --git a/lib/components/drawer/sidebar.dart b/lib/components/drawer/sidebar.dart index 0a245e6d2..8fbbbfa71 100644 --- a/lib/components/drawer/sidebar.dart +++ b/lib/components/drawer/sidebar.dart @@ -10,6 +10,7 @@ import 'package:rtchat/models/audio.dart'; import 'package:rtchat/models/channels.dart'; import 'package:rtchat/models/layout.dart'; import 'package:rtchat/models/qr_code.dart'; +import 'package:rtchat/models/quick_links.dart'; import 'package:rtchat/models/user.dart'; import 'package:rtchat/screens/settings/qr.dart'; import 'package:rtchat/urls.dart'; @@ -225,110 +226,126 @@ class Sidebar extends StatefulWidget { } class _SidebarState extends State { - @override - Widget build(BuildContext context) { - final tiles = [ - ListTile( - leading: const Icon(Icons.add_link_sharp), - title: Text(AppLocalizations.of(context)!.configureQuickLinks), - onTap: () => - Navigator.of(context).pushNamed("/settings/quick-links")), - - const Divider(), - - // setting - Consumer(builder: (context, layoutModel, child) { - if (!layoutModel.locked) { + Widget _buildActionTile(BuildContext context, String actionId) { + switch (actionId) { + case 'rainMode': + return Consumer(builder: (context, layoutModel, _) { return ListTile( leading: const Icon(Icons.thunderstorm), - title: Text(AppLocalizations.of(context)!.enableRainMode), - subtitle: Text(AppLocalizations.of(context)!.enableRainModeSubtitle, + title: Text(layoutModel.locked + ? AppLocalizations.of(context)!.disableRainMode + : AppLocalizations.of(context)!.enableRainMode), + subtitle: Text( + layoutModel.locked + ? AppLocalizations.of(context)!.disableRainModeSubtitle + : AppLocalizations.of(context)!.enableRainModeSubtitle, overflow: TextOverflow.ellipsis), - onTap: () async { + onTap: () { layoutModel.locked = !layoutModel.locked; Navigator.pop(context); }, ); - } - - return ListTile( - leading: const Icon(Icons.thunderstorm), - title: Text(AppLocalizations.of(context)!.disableRainMode), - subtitle: Text(AppLocalizations.of(context)!.disableRainModeSubtitle, - overflow: TextOverflow.ellipsis), - onTap: () async { - layoutModel.locked = !layoutModel.locked; - Navigator.pop(context); - }, - ); - }), - - Consumer(builder: (context, audioModel, child) { - if (audioModel.sources.isEmpty) { - return Container(); - } - return ListTile( - leading: const Icon(Icons.cached_outlined), - title: Text(AppLocalizations.of(context)!.refreshAudioSources), - onTap: () async { - final scaffoldMessenger = ScaffoldMessenger.of(context); - final count = await audioModel.refreshAllSources(); - if (!context.mounted) return; - scaffoldMessenger.showSnackBar(SnackBar( - content: Text(AppLocalizations.of(context)! - .refreshAudioSourcesCount(count)))); - }, - ); - }), + }); + case 'refreshAudio': + return Consumer(builder: (context, audioModel, _) { + if (audioModel.sources.isEmpty) return Container(); + return ListTile( + leading: const Icon(Icons.cached_outlined), + title: Text(AppLocalizations.of(context)!.refreshAudioSources), + onTap: () async { + final scaffoldMessenger = ScaffoldMessenger.of(context); + final count = await audioModel.refreshAllSources(); + if (!context.mounted) return; + scaffoldMessenger.showSnackBar(SnackBar( + content: Text(AppLocalizations.of(context)! + .refreshAudioSourcesCount(count)))); + }, + ); + }); + case 'raid': + return Consumer(builder: (context, model, _) { + return ListTile( + leading: const Icon(Icons.connect_without_contact), + title: Text(AppLocalizations.of(context)!.raidAChannel), + onTap: () { + Navigator.of(context).pop(); + showModalBottomSheet( + context: context, + isScrollControlled: true, + builder: (context) => _buildRaidBottomSheet(context), + ); + }, + ); + }); + default: + return const SizedBox.shrink(); + } + } - //raid - Consumer(builder: (context, model, child) { - return ListTile( - leading: const Icon(Icons.connect_without_contact), - title: Text(AppLocalizations.of(context)!.raidAChannel), - onTap: () { - Navigator.of(context).pop(); - showModalBottomSheet( - context: context, - isScrollControlled: true, - shape: const RoundedRectangleBorder( - borderRadius: BorderRadius.vertical(top: Radius.circular(16)), - ), - builder: (context) { - return DraggableScrollableSheet( - initialChildSize: 0.8, - maxChildSize: 0.9, - expand: false, - builder: (context, controller) { - final model = - Provider.of(context, listen: false); - final userChannel = model.userChannel; - return ChannelSearchBottomSheetWidget( - isRaid: true, - onChannelSelect: (channel) { - model.activeChannel = channel; - }, - onRaid: userChannel == model.activeChannel && - userChannel != null - ? (channel) { - final activeChannel = model.activeChannel; - if (activeChannel == null) { - return; - } - ActionsAdapter.instance - .raid(activeChannel, channel); - } - : null, - controller: controller, - ); - }, + Widget _buildRaidBottomSheet(BuildContext context) { + return DraggableScrollableSheet( + initialChildSize: 0.8, + maxChildSize: 0.9, + expand: false, + builder: (context, scrollController) { + return SingleChildScrollView( + controller: scrollController, + child: Container( + padding: EdgeInsets.only( + bottom: MediaQuery.of(context).viewInsets.bottom, + left: 16, + right: 16, + ), + child: Consumer( + builder: (context, model, _) { + final userChannel = model.userChannel; + return ConstrainedBox( + constraints: BoxConstraints( + minHeight: MediaQuery.of(context).size.height * 0.8, + maxHeight: MediaQuery.of(context).size.height * 0.9, + ), + child: ChannelSearchBottomSheetWidget( + isRaid: true, + onChannelSelect: (channel) { + model.activeChannel = channel; + }, + onRaid: userChannel == model.activeChannel && + userChannel != null + ? (channel) { + final activeChannel = model.activeChannel; + if (activeChannel == null) return; + ActionsAdapter.instance + .raid(activeChannel, channel); + } + : null, + controller: scrollController, + ), ); }, - ); - }, + ), + ), ); - }), + }, + ); + } + @override + Widget build(BuildContext context) { + final tiles = [ + ListTile( + leading: const Icon(Icons.add_link_sharp), + title: Text(AppLocalizations.of(context)!.configureQuickLinks), + onTap: () => + Navigator.of(context).pushNamed("/settings/quick-links")), + const Divider(), + Consumer( + builder: (context, model, _) => Column( + children: QuickLinksModel.availableActions + .where((action) => model.isActionEnabled(action['id'])) + .map((action) => _buildActionTile(context, action['id'])) + .toList(), + ), + ), ListTile( leading: const Icon(Icons.build_outlined), title: Text(AppLocalizations.of(context)!.settings), diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index 57696f1f8..eb56cbd21 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -1,3 +1,4 @@ + { "sendAMessage": "Send a message...", "@sendAMessage": { @@ -992,5 +993,9 @@ "alertsEnabled" : "Alerts only", "@alertsEnabled" : { "description": "Message indicating that alerts have been enabled" + }, + "sidebarActions": "Sidebar Actions", + "@sidebarActions": { + "description": "Header for the toggleable sidebar actions section" } } diff --git a/lib/models/quick_links.dart b/lib/models/quick_links.dart index 6f5fd906f..8bea234db 100644 --- a/lib/models/quick_links.dart +++ b/lib/models/quick_links.dart @@ -34,9 +34,39 @@ class QuickLinkSource { class QuickLinksModel extends ChangeNotifier { final List _sources = []; + final Set _enabledActions = {}; List get sources => _sources; + static const List> availableActions = [ + { + 'id': 'rainMode', + 'icon': Icons.thunderstorm, + 'labelKey': 'enableRainMode', + }, + { + 'id': 'refreshAudio', + 'icon': Icons.cached_outlined, + 'labelKey': 'refreshAudioSources', + }, + { + 'id': 'raid', + 'icon': Icons.connect_without_contact, + 'labelKey': 'raidAChannel', + }, + ]; + + bool isActionEnabled(String actionId) => _enabledActions.contains(actionId); + + void toggleAction(String actionId) { + if (_enabledActions.contains(actionId)) { + _enabledActions.remove(actionId); + } else { + _enabledActions.add(actionId); + } + notifyListeners(); + } + void addSource(QuickLinkSource source) { _sources.add(source); notifyListeners(); @@ -63,9 +93,18 @@ class QuickLinksModel extends ChangeNotifier { _sources.add(QuickLinkSource.fromJson(source)); } } + final enabledActions = json['enabledActions']; + if (enabledActions != null) { + for (dynamic action in enabledActions) { + if (action is String) { + _enabledActions.add(action); + } + } + } } Map toJson() => { "sources": _sources.map((source) => source.toJson()).toList(), + "enabledActions": _enabledActions.toList(), }; } diff --git a/lib/screens/settings/quick_links.dart b/lib/screens/settings/quick_links.dart index 1f5e37386..62de8c7b9 100644 --- a/lib/screens/settings/quick_links.dart +++ b/lib/screens/settings/quick_links.dart @@ -8,6 +8,21 @@ import 'package:rtchat/components/scanner_settings.dart'; import 'package:rtchat/models/quick_links.dart'; import 'package:rtchat/screens/settings/dismissible_delete_background.dart'; +extension LocalizedActions on AppLocalizations { + String getActionLabel(String key) { + switch (key) { + case 'enableRainMode': + return enableRainMode; + case 'refreshAudioSources': + return refreshAudioSources; + case 'raidAChannel': + return raidAChannel; + default: + return ''; + } + } +} + class QuickLinksScreen extends StatefulWidget { const QuickLinksScreen({super.key}); @@ -245,6 +260,30 @@ class _QuickLinksScreenState extends State { ]), ])), ), + const Divider(), + Padding( + padding: const EdgeInsets.all(16.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text(AppLocalizations.of(context)!.sidebarActions, + style: Theme.of(context).textTheme.titleMedium), + Consumer( + builder: (context, model, _) => Column( + children: QuickLinksModel.availableActions.map((action) { + return SwitchListTile( + title: Text(AppLocalizations.of(context)! + .getActionLabel(action['labelKey'])), + secondary: Icon(action['icon']), + value: model.isActionEnabled(action['id']), + onChanged: (_) => model.toggleAction(action['id']), + ); + }).toList(), + ), + ), + ], + ), + ), ]), ), ); From 7827b765dad016ef437ec8758a809ae667b026cb Mon Sep 17 00:00:00 2001 From: SputNikPlop <100245448+SputNikPlop@users.noreply.github.com> Date: Fri, 30 May 2025 09:07:11 -0700 Subject: [PATCH 2/2] fix: new localizations --- lib/l10n/app_localizations.dart | 6 ++++++ lib/l10n/app_localizations_ar.dart | 3 +++ lib/l10n/app_localizations_bn.dart | 3 +++ lib/l10n/app_localizations_de.dart | 3 +++ lib/l10n/app_localizations_en.dart | 3 +++ lib/l10n/app_localizations_es.dart | 3 +++ lib/l10n/app_localizations_fr.dart | 3 +++ lib/l10n/app_localizations_it.dart | 3 +++ lib/l10n/app_localizations_ja.dart | 3 +++ lib/l10n/app_localizations_ko.dart | 3 +++ lib/l10n/app_localizations_nl.dart | 3 +++ lib/l10n/app_localizations_pl.dart | 3 +++ lib/l10n/app_localizations_pt.dart | 3 +++ lib/l10n/app_localizations_ru.dart | 3 +++ lib/l10n/app_localizations_sv.dart | 3 +++ lib/l10n/app_localizations_uk.dart | 3 +++ lib/l10n/app_localizations_zh.dart | 3 +++ 17 files changed, 54 insertions(+) diff --git a/lib/l10n/app_localizations.dart b/lib/l10n/app_localizations.dart index 3123ced65..47cea8f01 100644 --- a/lib/l10n/app_localizations.dart +++ b/lib/l10n/app_localizations.dart @@ -1115,6 +1115,12 @@ abstract class AppLocalizations { /// In en, this message translates to: /// **'Alerts only'** String get alertsEnabled; + + /// Header for the toggleable sidebar actions section + /// + /// In en, this message translates to: + /// **'Sidebar Actions'** + String get sidebarActions; } class _AppLocalizationsDelegate diff --git a/lib/l10n/app_localizations_ar.dart b/lib/l10n/app_localizations_ar.dart index e67b18b1c..dc5329be2 100644 --- a/lib/l10n/app_localizations_ar.dart +++ b/lib/l10n/app_localizations_ar.dart @@ -697,4 +697,7 @@ class AppLocalizationsAr extends AppLocalizations { @override String get alertsEnabled => 'Alerts only'; + + @override + String get sidebarActions => 'Sidebar Actions'; } diff --git a/lib/l10n/app_localizations_bn.dart b/lib/l10n/app_localizations_bn.dart index 864f6b20d..776d85a9c 100644 --- a/lib/l10n/app_localizations_bn.dart +++ b/lib/l10n/app_localizations_bn.dart @@ -700,4 +700,7 @@ class AppLocalizationsBn extends AppLocalizations { @override String get alertsEnabled => 'Alerts only'; + + @override + String get sidebarActions => 'Sidebar Actions'; } diff --git a/lib/l10n/app_localizations_de.dart b/lib/l10n/app_localizations_de.dart index d1ec4e349..2e8f5ec88 100644 --- a/lib/l10n/app_localizations_de.dart +++ b/lib/l10n/app_localizations_de.dart @@ -707,4 +707,7 @@ class AppLocalizationsDe extends AppLocalizations { @override String get alertsEnabled => 'Alerts only'; + + @override + String get sidebarActions => 'Sidebar Actions'; } diff --git a/lib/l10n/app_localizations_en.dart b/lib/l10n/app_localizations_en.dart index 7f24554d8..4afc4f592 100644 --- a/lib/l10n/app_localizations_en.dart +++ b/lib/l10n/app_localizations_en.dart @@ -699,4 +699,7 @@ class AppLocalizationsEn extends AppLocalizations { @override String get alertsEnabled => 'Alerts only'; + + @override + String get sidebarActions => 'Sidebar Actions'; } diff --git a/lib/l10n/app_localizations_es.dart b/lib/l10n/app_localizations_es.dart index 9f8d05428..a5b9fae1c 100644 --- a/lib/l10n/app_localizations_es.dart +++ b/lib/l10n/app_localizations_es.dart @@ -700,4 +700,7 @@ class AppLocalizationsEs extends AppLocalizations { @override String get alertsEnabled => 'Alerts only'; + + @override + String get sidebarActions => 'Sidebar Actions'; } diff --git a/lib/l10n/app_localizations_fr.dart b/lib/l10n/app_localizations_fr.dart index 470aa1cb0..acb6bf4f1 100644 --- a/lib/l10n/app_localizations_fr.dart +++ b/lib/l10n/app_localizations_fr.dart @@ -711,4 +711,7 @@ class AppLocalizationsFr extends AppLocalizations { @override String get alertsEnabled => 'Alerts only'; + + @override + String get sidebarActions => 'Sidebar Actions'; } diff --git a/lib/l10n/app_localizations_it.dart b/lib/l10n/app_localizations_it.dart index ca0de2066..41b85fb18 100644 --- a/lib/l10n/app_localizations_it.dart +++ b/lib/l10n/app_localizations_it.dart @@ -708,4 +708,7 @@ class AppLocalizationsIt extends AppLocalizations { @override String get alertsEnabled => 'Alerts only'; + + @override + String get sidebarActions => 'Sidebar Actions'; } diff --git a/lib/l10n/app_localizations_ja.dart b/lib/l10n/app_localizations_ja.dart index 6243c2abb..054b04d0c 100644 --- a/lib/l10n/app_localizations_ja.dart +++ b/lib/l10n/app_localizations_ja.dart @@ -688,4 +688,7 @@ class AppLocalizationsJa extends AppLocalizations { @override String get alertsEnabled => 'Alerts only'; + + @override + String get sidebarActions => 'Sidebar Actions'; } diff --git a/lib/l10n/app_localizations_ko.dart b/lib/l10n/app_localizations_ko.dart index aecfcd460..95d291c24 100644 --- a/lib/l10n/app_localizations_ko.dart +++ b/lib/l10n/app_localizations_ko.dart @@ -688,4 +688,7 @@ class AppLocalizationsKo extends AppLocalizations { @override String get alertsEnabled => 'Alerts only'; + + @override + String get sidebarActions => 'Sidebar Actions'; } diff --git a/lib/l10n/app_localizations_nl.dart b/lib/l10n/app_localizations_nl.dart index 896382c9f..a3ca90d7e 100644 --- a/lib/l10n/app_localizations_nl.dart +++ b/lib/l10n/app_localizations_nl.dart @@ -703,4 +703,7 @@ class AppLocalizationsNl extends AppLocalizations { @override String get alertsEnabled => 'Alerts only'; + + @override + String get sidebarActions => 'Sidebar Actions'; } diff --git a/lib/l10n/app_localizations_pl.dart b/lib/l10n/app_localizations_pl.dart index e8f2143a8..8bf6c6060 100644 --- a/lib/l10n/app_localizations_pl.dart +++ b/lib/l10n/app_localizations_pl.dart @@ -704,4 +704,7 @@ class AppLocalizationsPl extends AppLocalizations { @override String get alertsEnabled => 'Alerts only'; + + @override + String get sidebarActions => 'Sidebar Actions'; } diff --git a/lib/l10n/app_localizations_pt.dart b/lib/l10n/app_localizations_pt.dart index a2adbd0a9..d8f2cfe53 100644 --- a/lib/l10n/app_localizations_pt.dart +++ b/lib/l10n/app_localizations_pt.dart @@ -704,4 +704,7 @@ class AppLocalizationsPt extends AppLocalizations { @override String get alertsEnabled => 'Alerts only'; + + @override + String get sidebarActions => 'Sidebar Actions'; } diff --git a/lib/l10n/app_localizations_ru.dart b/lib/l10n/app_localizations_ru.dart index cbb436e84..4a6eb2921 100644 --- a/lib/l10n/app_localizations_ru.dart +++ b/lib/l10n/app_localizations_ru.dart @@ -708,4 +708,7 @@ class AppLocalizationsRu extends AppLocalizations { @override String get alertsEnabled => 'Alerts only'; + + @override + String get sidebarActions => 'Sidebar Actions'; } diff --git a/lib/l10n/app_localizations_sv.dart b/lib/l10n/app_localizations_sv.dart index fa0e14700..fa5ffeab8 100644 --- a/lib/l10n/app_localizations_sv.dart +++ b/lib/l10n/app_localizations_sv.dart @@ -698,4 +698,7 @@ class AppLocalizationsSv extends AppLocalizations { @override String get alertsEnabled => 'Alerts only'; + + @override + String get sidebarActions => 'Sidebar Actions'; } diff --git a/lib/l10n/app_localizations_uk.dart b/lib/l10n/app_localizations_uk.dart index 5226f6849..3fd43b022 100644 --- a/lib/l10n/app_localizations_uk.dart +++ b/lib/l10n/app_localizations_uk.dart @@ -707,4 +707,7 @@ class AppLocalizationsUk extends AppLocalizations { @override String get alertsEnabled => 'Alerts only'; + + @override + String get sidebarActions => 'Sidebar Actions'; } diff --git a/lib/l10n/app_localizations_zh.dart b/lib/l10n/app_localizations_zh.dart index 0863a765f..2713a77cc 100644 --- a/lib/l10n/app_localizations_zh.dart +++ b/lib/l10n/app_localizations_zh.dart @@ -687,6 +687,9 @@ class AppLocalizationsZh extends AppLocalizations { @override String get alertsEnabled => 'Alerts only'; + + @override + String get sidebarActions => 'Sidebar Actions'; } /// The translations for Chinese, using the Han script (`zh_Hant`).