From 0780e9b037d8ad1d3f2e5600d79a00e7bbfb04f9 Mon Sep 17 00:00:00 2001 From: CodeDoctorDE Date: Sun, 15 Dec 2024 13:10:02 +0100 Subject: [PATCH] Reimplement shortcuts for search --- app/lib/views/app_bar.dart | 16 ++++++++++++++-- app/lib/views/main.dart | 21 ++++++++++++++++++++- app/lib/widgets/search.dart | 29 ++++++++++++++++++++++------- 3 files changed, 56 insertions(+), 10 deletions(-) diff --git a/app/lib/views/app_bar.dart b/app/lib/views/app_bar.dart index fd85b903c888..c6bb92084721 100644 --- a/app/lib/views/app_bar.dart +++ b/app/lib/views/app_bar.dart @@ -37,8 +37,14 @@ import 'navigator/view.dart'; class PadAppBar extends StatelessWidget implements PreferredSizeWidget { final GlobalKey viewportKey; final ToolbarSize size; + final SearchController searchController; - PadAppBar({super.key, required this.viewportKey, required this.size}); + PadAppBar({ + super.key, + required this.viewportKey, + required this.size, + required this.searchController, + }); late final windowTitleBar = _buildWindowTitleBar(); @@ -67,6 +73,7 @@ class PadAppBar extends StatelessWidget implements PreferredSizeWidget { MediaQuery.of(context).size.width < LeapBreakpoints.compact; return _AppBarTitle( isMobile: isMobile, + searchController: searchController, ); }), ); @@ -76,8 +83,11 @@ class PadAppBar extends StatelessWidget implements PreferredSizeWidget { } class _AppBarTitle extends StatefulWidget { + final SearchController searchController; + const _AppBarTitle({ required this.isMobile, + required this.searchController, }); final bool isMobile; @@ -298,7 +308,9 @@ class _AppBarTitleState extends State<_AppBarTitle> { state.location.fileType.icon(PhosphorIconsStyle.light)), tooltip: AppLocalizations.of(context).export, onPressed: () => context.read().export()), - SearchButton(), + SearchButton( + controller: widget.searchController, + ), if (state.location.path != '' && state.embedding == null) ...[ IconButton( icon: const PhosphorIcon(PhosphorIconsLight.folder), diff --git a/app/lib/views/main.dart b/app/lib/views/main.dart index c547a42c4a98..b13fb9b7ca43 100644 --- a/app/lib/views/main.dart +++ b/app/lib/views/main.dart @@ -18,6 +18,7 @@ import 'package:butterfly/views/toolbar/view.dart'; import 'package:butterfly/views/edit.dart'; import 'package:butterfly/views/error.dart'; import 'package:butterfly/views/property.dart'; +import 'package:butterfly/widgets/search.dart'; import 'package:butterfly_api/butterfly_api.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; @@ -87,6 +88,7 @@ class _ProjectPageState extends State { ExternalStorage? _remote; ImportService? _importService; ExportService? _exportService; + final SearchController _searchController = SearchController(); late final CloseSubscription _closeSubscription; final GlobalKey _viewportKey = GlobalKey(); final _actions = >{ @@ -286,6 +288,7 @@ class _ProjectPageState extends State { widget.embedding?.handler.unregister(); _closeSubscription.dispose(); _bloc?.dispose(); + _searchController.dispose(); } @override @@ -331,7 +334,19 @@ class _ProjectPageState extends State { previous.toolbarSize != current.toolbarSize, builder: (context, settings) { return Actions( - actions: _actions, + actions: { + ..._actions, + SearchIntent: CallbackAction( + onInvoke: (_) { + if (_searchController.isOpen) { + _searchController.closeView(null); + return null; + } + _searchController.openView(); + return null; + }, + ), + }, child: Shortcuts( shortcuts: { LogicalKeySet(LogicalKeyboardKey.control, @@ -364,6 +379,8 @@ class _ProjectPageState extends State { LogicalKeySet(LogicalKeyboardKey.control, LogicalKeyboardKey.keyA): SelectAllIntent(context), + LogicalKeySet(LogicalKeyboardKey.control, + LogicalKeyboardKey.keyK): SearchIntent(), if (widget.embedding == null) ...{ LogicalKeySet(LogicalKeyboardKey.control, LogicalKeyboardKey.keyE): @@ -441,6 +458,8 @@ class _ProjectPageState extends State { : PadAppBar( viewportKey: _viewportKey, size: settings.toolbarSize, + searchController: + _searchController, ), drawer: state is DocumentLoadSuccess ? const DocumentNavigator( diff --git a/app/lib/widgets/search.dart b/app/lib/widgets/search.dart index 211aa683e544..f21a3214948c 100644 --- a/app/lib/widgets/search.dart +++ b/app/lib/widgets/search.dart @@ -11,6 +11,10 @@ import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:material_leap/material_leap.dart'; import 'package:phosphor_flutter/phosphor_flutter.dart'; +class SearchIntent extends Intent { + const SearchIntent(); +} + Future> _searchIsolate(NoteData noteData, String currentPage, DocumentPage page, String query) => Isolate.run(() => noteData @@ -18,7 +22,8 @@ Future> _searchIsolate(NoteData noteData, String currentPage, .toList()); class SearchButton extends StatelessWidget { - const SearchButton({super.key}); + final SearchController controller; + const SearchButton({super.key, required this.controller}); IconGetter _getIcon(SearchResult item) => switch (item) { ElementResult e => e.element.icon, @@ -49,13 +54,23 @@ class SearchButton extends StatelessWidget { Widget build(BuildContext context) { final bloc = context.read(); return SearchAnchor( - builder: (BuildContext context, SearchController controller) => - IconButton( - icon: const Icon(PhosphorIconsLight.magnifyingGlass), - tooltip: AppLocalizations.of(context).search, - onPressed: () { - controller.openView(); + searchController: controller, + builder: (BuildContext context, SearchController controller) => Actions( + actions: { + SearchIntent: CallbackAction( + onInvoke: (_) { + controller.openView(); + return null; + }, + ), }, + child: IconButton( + icon: const Icon(PhosphorIconsLight.magnifyingGlass), + tooltip: AppLocalizations.of(context).search, + onPressed: () { + controller.openView(); + }, + ), ), suggestionsBuilder: (context, controller) async { final state = bloc.state;