Skip to content

Commit

Permalink
Merge branch 'development'
Browse files Browse the repository at this point in the history
Release 0.6.0
  • Loading branch information
TNorbury committed Dec 11, 2022
2 parents 4472fd7 + 25d1b34 commit 89cafbe
Show file tree
Hide file tree
Showing 11 changed files with 160 additions and 114 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## 0.6.0 - 2022-12-10
### Fixed
- Semi-Breaking: Changed the type of `CommandPaletteConfig.openKeySet` and `CommandPaletteConfig.closeKeySet` from `LogicalKeySet` to `ShortcutActivator` (note: `LogicalKeySet` already implements `ShortcutActivator`, so existing custom shortcuts should still work, but a proposed solution is discussed below). This was done to fix an issue on Web builds for MacOS (discussed [here](https://github.com/TNorbury/command_palette/issues/22)). If you don't set custom values for the open and close key sets (or if you're not targeting Web), then no change will be required on your part. But if you are, the following change is suggested to make sure everything works well: If you're opening the palette with a keyboard shortcut, such as CTRL/CMD+U, then you could go from `LogicalKeySet(LogicalKeyboardKey.control, LogicalKeyboardKey.keyU)`/`LogicalKeySet(LogicalKeyboardKey.meta, LogicalKeyboardKey.keyU)` to `SingleActivator(LogicalKeyboardKey.keyU, control: true)`/`SingleActivator(LogicalKeyboardKey.keyU, meta: true)`. This also changes how the command palette control shortcuts (Up/down/enter/backspace) are handled (from `LogicalKeySet` to `SingleActivator`). This should make things a bit cleaner on my end, and more stable going forward.
- Escape query correctly so that single a '' don't cause filtering to crash

## 0.5.1 - 2022-12-02
### Added
- Optional `leading` widget for `CommandPaletteAction`s which will display a Widget at the left-side of the different command palette options
Expand Down
6 changes: 1 addition & 5 deletions example/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import 'dart:math';
import 'package:command_palette/command_palette.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_lorem/flutter_lorem.dart';

void main() {
runApp(const MyApp());
Expand Down Expand Up @@ -56,10 +55,7 @@ class _MyHomePageState extends State<MyHomePage> {
),

// Setting custom keyboard shortcuts
// openKeySet: LogicalKeySet(
// LogicalKeyboardKey.alt,
// LogicalKeyboardKey.keyO,
// ),
// openKeySet: SingleActivator(LogicalKeyboardKey.keyP, meta: true),
// closeKeySet: LogicalKeySet(
// LogicalKeyboardKey.control,
// LogicalKeyboardKey.keyC,
Expand Down
2 changes: 1 addition & 1 deletion example/pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ packages:
path: ".."
relative: true
source: path
version: "0.5.1"
version: "0.6.0"
fake_async:
dependency: transitive
description:
Expand Down
46 changes: 27 additions & 19 deletions lib/src/command_palette.dart
Original file line number Diff line number Diff line change
Expand Up @@ -138,11 +138,16 @@ class _CommandPaletteInnerState extends State<_CommandPaletteInner> {
void didUpdateWidget(covariant _CommandPaletteInner oldWidget) {
super.didUpdateWidget(oldWidget);

if (oldWidget.config != widget.config ||
oldWidget.actions != widget.actions) {
final bool actionsChanged = !listEquals(oldWidget.actions, widget.actions);

if (oldWidget.config != widget.config || actionsChanged) {
_initStyle();
}

// if (actionsChanged) {
// widget.controller.actions = widget.actions;
// }

// refresh toggler listeners if need be
if (oldWidget.toggler != widget.toggler) {
oldWidget.toggler.removeListener(_handleToggle);
Expand Down Expand Up @@ -221,24 +226,23 @@ class _CommandPaletteInnerState extends State<_CommandPaletteInner> {
controller: widget.controller,
child: Builder(
builder: (context) {
return Focus(
autofocus: true,
onKey: (node, event) {
KeyEventResult result = KeyEventResult.ignored;

// if ctrl-c is pressed, and the command palette isn't open,
// open it
if (widget.config.openKeySet
.accepts(event, RawKeyboard.instance) &&
!_commandPaletteOpen) {
_openCommandPalette(context);

result = KeyEventResult.handled;
}

return result;
return Shortcuts(
shortcuts: {
widget.config.openKeySet: const _OpenCommandPaletteIntent()
},
child: widget.child,
child: Actions(
actions: {
_OpenCommandPaletteIntent:
CallbackAction<_OpenCommandPaletteIntent>(
// ignore: body_might_complete_normally_nullable
onInvoke: (_) => _openCommandPalette(context),
)
},
child: Focus(
autofocus: true,
child: widget.child,
),
),
);
},
),
Expand Down Expand Up @@ -282,3 +286,7 @@ class _CommandPaletteInnerState extends State<_CommandPaletteInner> {
Navigator.of(context).pop();
}
}

class _OpenCommandPaletteIntent extends Intent {
const _OpenCommandPaletteIntent();
}
20 changes: 10 additions & 10 deletions lib/src/controller/command_palette_controller.dart
Original file line number Diff line number Diff line change
Expand Up @@ -134,19 +134,19 @@ class CommandPaletteController extends ChangeNotifier {
return filteredActions;
}

/// Handles backspace being pressed. The order of actions is as follows
/// 1. If there is text in the controller, the backspace works as expected
/// there (i.e. deletes the character right behind the cursor)
/// 2. If an action is currently selected, we'll pop one level
bool handleBackspace() {
bool handled = false;

/// Determines if the backspace will be handled by the command palette.
/// The following things determine if it'll be handled:
/// 1. If there is text in the text field, the backspace won't be handled here
/// and instead be passed on, behaving as a backspace is expected to (i.e.
/// deletes a character). False will be returned
/// 2. If no text is present, and an action is selected, this will return true.
/// otherwise false.
bool backspaceWillBeHandled() {
if (textEditingController.text.isNotEmpty) {
handled = false;
return false;
} else {
handled = gotoParentAction();
return currentlySelectedAction != null;
}
return handled;
}

/// Goes a level up in the action tree, and sets the selected action as the
Expand Down
16 changes: 8 additions & 8 deletions lib/src/models/command_palette_config.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@ import 'package:flutter/services.dart';

import '../../command_palette.dart';

final _defaultOpenKeySet = defaultTargetPlatform == TargetPlatform.macOS
? LogicalKeySet(LogicalKeyboardKey.meta, LogicalKeyboardKey.keyK)
: LogicalKeySet(LogicalKeyboardKey.control, LogicalKeyboardKey.keyK);
final _defaultCloseKeySet = LogicalKeySet(LogicalKeyboardKey.escape);
final _defaultOpenKeySet = SingleActivator(LogicalKeyboardKey.keyK,
meta: defaultTargetPlatform == TargetPlatform.macOS,
control: defaultTargetPlatform != TargetPlatform.macOS);
const _defaultCloseKeySet = SingleActivator(LogicalKeyboardKey.escape);

/// Configuration options for the command palette
class CommandPaletteConfig {
Expand Down Expand Up @@ -47,7 +47,7 @@ class CommandPaletteConfig {
/// The set of keys used to open the command palette.
///
/// Defaults to Ctrl-/Cmd- C
final LogicalKeySet openKeySet;
final ShortcutActivator openKeySet;

/// The set of keys used to close the command palette.
///
Expand All @@ -57,7 +57,7 @@ class CommandPaletteConfig {
/// App-level. If you want to prevent this, see: https://stackoverflow.com/questions/63763478/disable-escape-key-navigation-in-flutter-web
///
/// Defaults to Esc.
final LogicalKeySet closeKeySet;
final ShortcutActivator closeKeySet;

/// The offset of the modal from the top of the screen.
///
Expand Down Expand Up @@ -103,8 +103,8 @@ class CommandPaletteConfig {
ActionFilter? filter,
Key? key,
ActionBuilder? builder,
LogicalKeySet? openKeySet,
LogicalKeySet? closeKeySet,
ShortcutActivator? openKeySet,
ShortcutActivator? closeKeySet,
this.hintText = "Begin typing to search for something",
this.transitionDuration = const Duration(milliseconds: 150),
this.transitionCurve = Curves.linear,
Expand Down
4 changes: 2 additions & 2 deletions lib/src/utils/filter.dart
Original file line number Diff line number Diff line change
Expand Up @@ -89,9 +89,9 @@ class Filter {
}

static String convertToRegExpPattern(String word) {
return word
return RegExp.escape(word
.replaceAll(r'/[\-\\\{\}\+\?\|\^\$\.\,\[\]\(\)\#\s]/g', '\\\$&')
.replaceAll(r"/[\*]/g", ".*");
.replaceAll(r"/[\*]/g", ".*"));
}

/// Matches a non-contiguous sub-string
Expand Down
150 changes: 88 additions & 62 deletions lib/src/widgets/command_palette_modal.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
// ignore_for_file: body_might_complete_normally_nullable

import 'package:command_palette/src/controller/command_palette_controller.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
Expand All @@ -23,7 +25,7 @@ class CommandPaletteModal extends ModalRoute<void> {

final Curve _transitionCurve;

final LogicalKeySet closeKeySet;
final ShortcutActivator closeKeySet;

@override
void dispose() {
Expand Down Expand Up @@ -100,70 +102,62 @@ class CommandPaletteModal extends ModalRoute<void> {
bottom: bottom,
left: left,
right: right,
child: Focus(
// not sure why but this seems to make things play nice lol
onKeyEvent: (node, event) => KeyEventResult.ignored,
onKey: (node, event) {
KeyEventResult result = KeyEventResult.ignored;

if (LogicalKeySet(LogicalKeyboardKey.backspace)
.accepts(event, RawKeyboard.instance)) {
if (commandPaletteController.handleBackspace()) {
result = KeyEventResult.handled;
}
}

// down, move selector down
else if (LogicalKeySet(LogicalKeyboardKey.arrowDown)
.accepts(event, RawKeyboard.instance)) {
commandPaletteController.movedHighlightedAction(
down: true,
);
result = KeyEventResult.handled;
}

// up, move selector up
else if (LogicalKeySet(LogicalKeyboardKey.arrowUp)
.accepts(event, RawKeyboard.instance)) {
commandPaletteController.movedHighlightedAction(
down: false,
);
result = KeyEventResult.handled;
}

// enter makes selection
else if (LogicalKeySet(LogicalKeyboardKey.enter)
.accepts(event, RawKeyboard.instance)) {
commandPaletteController
.performHighlightedAction(context);
result = KeyEventResult.handled;
}

// close the command palette
else if (closeKeySet.accepts(
event,
RawKeyboard.instance,
)) {
Navigator.of(context).pop();
result = KeyEventResult.handled;
}

return result;
child: Shortcuts(
shortcuts: {
const SingleActivator(LogicalKeyboardKey.backspace):
const _BackspaceIntent(),
const SingleActivator(LogicalKeyboardKey.arrowDown):
const _DownArrowIntent(),
const SingleActivator(LogicalKeyboardKey.arrowUp):
const _UpArrowIntent(),
const SingleActivator(LogicalKeyboardKey.enter):
const _EnterIntent(),
closeKeySet: const _CloseIntent(),
},
child: SizedBox(
height: height,
width: width,
child: Column(
children: [
CommandPaletteTextField(
hintText: hintText,
onSubmit: () => commandPaletteController
.performHighlightedAction(context),
child: Actions(
actions: {
_BackspaceIntent: _BackspaceAction(
onInvoke: (intent) =>
commandPaletteController.gotoParentAction(),
controller: commandPaletteController,
),
_DownArrowIntent: CallbackAction<_DownArrowIntent>(
onInvoke: (intent) =>
commandPaletteController.movedHighlightedAction(
down: true,
),
),
_UpArrowIntent: CallbackAction<_UpArrowIntent>(
onInvoke: (intent) =>
commandPaletteController.movedHighlightedAction(
down: false,
),
const Flexible(
child: CommandPaletteBody(),
),
_EnterIntent: CallbackAction<_EnterIntent>(
onInvoke: (intent) => commandPaletteController
.performHighlightedAction(context),
),
_CloseIntent: CallbackAction<_CloseIntent>(
onInvoke: (intent) => Navigator.of(context).pop(),
),
},
child: Focus(
child: SizedBox(
height: height,
width: width,
child: Column(
children: [
CommandPaletteTextField(
hintText: hintText,
onSubmit: () => commandPaletteController
.performHighlightedAction(context),
),
const Flexible(
child: CommandPaletteBody(),
),
],
),
],
),
),
),
),
Expand All @@ -176,3 +170,35 @@ class CommandPaletteModal extends ModalRoute<void> {
);
}
}

// intents for the different control keys
class _BackspaceIntent extends Intent {
const _BackspaceIntent();
}

class _DownArrowIntent extends Intent {
const _DownArrowIntent();
}

class _UpArrowIntent extends Intent {
const _UpArrowIntent();
}

class _EnterIntent extends Intent {
const _EnterIntent();
}

class _CloseIntent extends Intent {
const _CloseIntent();
}

class _BackspaceAction extends CallbackAction<_BackspaceIntent> {
CommandPaletteController controller;
_BackspaceAction({
required OnInvokeCallback<_BackspaceIntent> onInvoke,
required this.controller,
}) : super(onInvoke: onInvoke);

@override
bool isEnabled(_) => controller.backspaceWillBeHandled();
}
2 changes: 1 addition & 1 deletion pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name: command_palette
description: Flutter implementation of the Command Palette. Can be brought up via a keyboard shortcut.
version: 0.5.1
version: 0.6.0
homepage: https://github.com/TNorbury/command_palette
issue_tracker: https://github.com/TNorbury/command_palette/issues
repository: https://github.com/TNorbury/command_palette
Expand Down
Loading

0 comments on commit 89cafbe

Please sign in to comment.