Support local filter for selection query

This commit is contained in:
qianlifeng 2024-10-21 00:03:40 +08:00
parent 80456fa00e
commit ebdf41f76b
No known key found for this signature in database
4 changed files with 62 additions and 25 deletions

View File

@ -1,5 +1,3 @@
import 'dart:io';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:hotkey_manager/hotkey_manager.dart'; import 'package:hotkey_manager/hotkey_manager.dart';

View File

@ -34,6 +34,7 @@ import 'package:wox/utils/picker.dart';
import 'package:wox/utils/wox_setting_util.dart'; import 'package:wox/utils/wox_setting_util.dart';
import 'package:wox/utils/wox_theme_util.dart'; import 'package:wox/utils/wox_theme_util.dart';
import 'package:wox/utils/wox_websocket_msg_util.dart'; import 'package:wox/utils/wox_websocket_msg_util.dart';
import 'package:fuzzywuzzy/fuzzywuzzy.dart';
class WoxLauncherController extends GetxController { class WoxLauncherController extends GetxController {
//query related variables //query related variables
@ -52,6 +53,7 @@ class WoxLauncherController extends GetxController {
final activeResultIndex = 0.obs; final activeResultIndex = 0.obs;
final resultGlobalKeys = <GlobalKey>[]; // the global keys for each result item, used to calculate the position of the result item final resultGlobalKeys = <GlobalKey>[]; // the global keys for each result item, used to calculate the position of the result item
final resultScrollerController = ScrollController(initialScrollOffset: 0.0); final resultScrollerController = ScrollController(initialScrollOffset: 0.0);
final originalResults = <WoxQueryResult>[]; // the original results, used to filter and restore selection results
/// The timer to clear query results. /// The timer to clear query results.
/// On every query changed, it will reset the timer and will clear the query results after N ms. /// On every query changed, it will reset the timer and will clear the query results after N ms.
@ -139,6 +141,7 @@ class WoxLauncherController extends GetxController {
} }
results.assignAll(finalResultsSorted); results.assignAll(finalResultsSorted);
originalResults.assignAll(results);
for (var _ in results) { for (var _ in results) {
resultGlobalKeys.add(GlobalKey()); resultGlobalKeys.add(GlobalKey());
} }
@ -333,20 +336,35 @@ class WoxLauncherController extends GetxController {
void onQueryBoxTextChanged(String value) { void onQueryBoxTextChanged(String value) {
canArrowUpHistory = false; canArrowUpHistory = false;
PlainQuery plainQuery = PlainQuery(
queryId: const UuidV4().generate(),
queryType: WoxQueryTypeEnum.WOX_QUERY_TYPE_INPUT.code,
queryText: value,
querySelection: Selection.empty(),
);
// do filter if query type is selection
if (currentQuery.value.queryType == WoxQueryTypeEnum.WOX_QUERY_TYPE_SELECTION.code) { if (currentQuery.value.queryType == WoxQueryTypeEnum.WOX_QUERY_TYPE_SELECTION.code) {
plainQuery.queryType = WoxQueryTypeEnum.WOX_QUERY_TYPE_SELECTION.code; // do local filter if query type is selection
plainQuery.querySelection = currentQuery.value.querySelection; filterSelectionResults(const UuidV4().generate(), value);
} else {
onQueryChanged(
const UuidV4().generate(),
PlainQuery(
queryId: const UuidV4().generate(),
queryType: WoxQueryTypeEnum.WOX_QUERY_TYPE_INPUT.code,
queryText: value,
querySelection: Selection.empty(),
),
"user input changed",
);
}
}
void filterSelectionResults(String traceId, String filterText) {
if (filterText.isEmpty) {
results.assignAll(originalResults);
} else {
var matchedResults = originalResults.where((result) {
return isFuzzyMatch(traceId, result.title.value, filterText) || isFuzzyMatch(traceId, result.subTitle.value, filterText);
}).toList();
results.assignAll(matchedResults);
} }
onQueryChanged(const UuidV4().generate(), plainQuery, "user input changed"); resetActiveResult();
resetActiveAction(traceId, "filter selection results: $filterText");
} }
void onQueryChanged(String traceId, PlainQuery query, String changeReason, {bool moveCursorToEnd = false}) { void onQueryChanged(String traceId, PlainQuery query, String changeReason, {bool moveCursorToEnd = false}) {
@ -417,11 +435,7 @@ class WoxLauncherController extends GetxController {
} }
var filteredActions = activeResult.actions.where((element) { var filteredActions = activeResult.actions.where((element) {
if (WoxSettingUtil.instance.currentSetting.usePinYin) { return isFuzzyMatch(traceId, element.name.value, queryAction);
return transferChineseToPinYin(element.name.toLowerCase()).contains(queryAction.toLowerCase());
}
return element.name.toLowerCase().contains(queryAction.toLowerCase());
}).toList(); }).toList();
//if filtered actions is not changed, then return //if filtered actions is not changed, then return
@ -433,6 +447,19 @@ class WoxLauncherController extends GetxController {
updateToolbarByActiveAction(traceId); updateToolbarByActiveAction(traceId);
} }
/// check if the query text is fuzzy match with the filter text based on the setting
bool isFuzzyMatch(String traceId, String queryText, String filterText) {
if (WoxSettingUtil.instance.currentSetting.usePinYin) {
queryText = transferChineseToPinYin(queryText).toLowerCase();
} else {
queryText = queryText.toLowerCase();
}
var score = weightedRatio(queryText, filterText.toLowerCase());
Logger.instance.debug(traceId, "calculate fuzzy match score, queryText: $queryText, filterText: $filterText, score: $score");
return score > 50;
}
void changeResultScrollPosition(String traceId, WoxEventDeviceType deviceType, WoxDirection direction) { void changeResultScrollPosition(String traceId, WoxEventDeviceType deviceType, WoxDirection direction) {
final prevResultIndex = activeResultIndex.value; final prevResultIndex = activeResultIndex.value;
updateActiveResultIndex(traceId, direction); updateActiveResultIndex(traceId, direction);
@ -575,13 +602,16 @@ class WoxLauncherController extends GetxController {
/// reset and jump active result to top of the list /// reset and jump active result to top of the list
void resetActiveResult() { void resetActiveResult() {
if (results[0].isGroup) { // reset active result index
activeResultIndex.value = 1; if (results.isNotEmpty) {
} else { if (results[0].isGroup) {
activeResultIndex.value = 0; activeResultIndex.value = 1;
} } else {
if (resultScrollerController.hasClients) { activeResultIndex.value = 0;
resultScrollerController.jumpTo(0); }
if (resultScrollerController.hasClients) {
resultScrollerController.jumpTo(0);
}
} }
//reset preview //reset preview

View File

@ -301,6 +301,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.0.0" version: "2.0.0"
fuzzywuzzy:
dependency: "direct main"
description:
name: fuzzywuzzy
sha256: "3004379ffd6e7f476a0c2091f38f16588dc45f67de7adf7c41aa85dec06b432c"
url: "https://pub.dev"
source: hosted
version: "1.2.0"
get: get:
dependency: "direct main" dependency: "direct main"
description: description:

View File

@ -61,6 +61,7 @@ dependencies:
flutter_highlight: ^0.7.0 flutter_highlight: ^0.7.0
highlight: ^0.7.0 highlight: ^0.7.0
lottie: ^3.1.2 lottie: ^3.1.2
fuzzywuzzy: ^1.2.0
dev_dependencies: dev_dependencies:
flutter_test: flutter_test: