mirror of https://github.com/Wox-launcher/Wox
feat(ui): enhance input method switching on query box focus
* Updated the input method switch logic to trigger when the query box gains focus. * Improved user experience by providing clearer instructions in the UI language files. * Added a new API endpoint for handling query box focus events. * Implemented caching for image rendering to reduce flickering during refreshes.
This commit is contained in:
parent
f53df14bf8
commit
8e5adf7c5c
|
@ -23,7 +23,7 @@
|
|||
"ui_show_position_active_screen": "Active screen",
|
||||
"ui_show_position_last_location": "Last location",
|
||||
"ui_switch_input_method_abc": "Switch to ABC",
|
||||
"ui_switch_input_method_abc_tips": "When selected, the input method will be switched to english",
|
||||
"ui_switch_input_method_abc_tips": "When selected, the input method will be switched to english when the query box gains focus",
|
||||
"ui_lang": "Language",
|
||||
"ui_query_hotkeys": "Query Hotkeys",
|
||||
"ui_query_shortcuts": "Query Shortcuts",
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
"ui_show_position_active_screen": "Tela ativa",
|
||||
"ui_show_position_last_location": "Última posição",
|
||||
"ui_switch_input_method_abc": "Alternar para ABC",
|
||||
"ui_switch_input_method_abc_tips": "Quando selecionado, o método de entrada será alterado para o inglês",
|
||||
"ui_switch_input_method_abc_tips": "Quando selecionado, o método de entrada será alterado para o inglês quando a caixa de consulta receber o foco",
|
||||
"ui_lang": "Idioma",
|
||||
"ui_query_hotkeys": "Teclas de atalho para consulta",
|
||||
"ui_query_shortcuts": "Atalhos de consulta",
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
"ui_show_position_active_screen": "Активный экран",
|
||||
"ui_show_position_last_location": "Последнее положение",
|
||||
"ui_switch_input_method_abc": "Переключить на ABC",
|
||||
"ui_switch_input_method_abc_tips": "При выборе метод ввода будет переключен на английский",
|
||||
"ui_switch_input_method_abc_tips": "При выборе метод ввода будет переключен на английский при получении фокуса полем запроса",
|
||||
"ui_lang": "Язык",
|
||||
"ui_query_hotkeys": "Горячие клавиши запроса",
|
||||
"ui_query_shortcuts": "Ярлыки запросов",
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
"ui_show_position_active_screen": "活动屏幕",
|
||||
"ui_show_position_last_location": "上次位置",
|
||||
"ui_switch_input_method_abc": "切换输入法",
|
||||
"ui_switch_input_method_abc_tips": "选中后,输入法将切换到英文",
|
||||
"ui_switch_input_method_abc_tips": "选中后,查询框获得焦点时输入法将切换到英文",
|
||||
"ui_lang": "语言",
|
||||
"ui_query_hotkeys": "查询快捷",
|
||||
"ui_query_shortcuts": "查询缩写",
|
||||
|
|
|
@ -419,9 +419,13 @@ func (m *Manager) PostUIReady(ctx context.Context) {
|
|||
}
|
||||
|
||||
func (m *Manager) PostOnShow(ctx context.Context) {
|
||||
//no-op
|
||||
}
|
||||
|
||||
func (m *Manager) PostOnQueryBoxFocus(ctx context.Context) {
|
||||
woxSetting := setting.GetSettingManager().GetWoxSetting(ctx)
|
||||
if woxSetting.SwitchInputMethodABC {
|
||||
util.GetLogger().Info(ctx, "switch input method to ABC")
|
||||
util.GetLogger().Info(ctx, "switch input method to ABC on query box focus")
|
||||
switchErr := ime.SwitchInputMethodABC()
|
||||
if switchErr != nil {
|
||||
logger.Error(ctx, fmt.Sprintf("failed to switch input method to ABC: %s", switchErr.Error()))
|
||||
|
|
|
@ -53,6 +53,7 @@ var routers = map[string]func(w http.ResponseWriter, r *http.Request){
|
|||
"/on/focus/lost": handleOnFocusLost,
|
||||
"/on/ready": handleOnUIReady,
|
||||
"/on/show": handleOnShow,
|
||||
"/on/querybox/focus": handleOnQueryBoxFocus,
|
||||
"/on/hide": handleOnHide,
|
||||
|
||||
// lang
|
||||
|
@ -699,6 +700,12 @@ func handleOnShow(w http.ResponseWriter, r *http.Request) {
|
|||
writeSuccessResponse(w, "")
|
||||
}
|
||||
|
||||
func handleOnQueryBoxFocus(w http.ResponseWriter, r *http.Request) {
|
||||
ctx := util.NewTraceContext()
|
||||
GetUIManager().PostOnQueryBoxFocus(ctx)
|
||||
writeSuccessResponse(w, "")
|
||||
}
|
||||
|
||||
func handleOnHide(w http.ResponseWriter, r *http.Request) {
|
||||
ctx := util.NewTraceContext()
|
||||
|
||||
|
|
|
@ -99,6 +99,10 @@ class WoxApi {
|
|||
await WoxHttpUtil.instance.postData("/on/show", {});
|
||||
}
|
||||
|
||||
Future<void> onQueryBoxFocus() async {
|
||||
await WoxHttpUtil.instance.postData("/on/querybox/focus", {});
|
||||
}
|
||||
|
||||
Future<void> onHide(PlainQuery query) async {
|
||||
await WoxHttpUtil.instance.postData("/on/hide", {
|
||||
"query": query.toJson(),
|
||||
|
|
|
@ -9,6 +9,21 @@ import 'package:wox/entity/wox_image.dart';
|
|||
import 'package:wox/entity/wox_theme.dart';
|
||||
import 'package:wox/enums/wox_image_type_enum.dart';
|
||||
|
||||
// Image cache to prevent flickering during refreshes
|
||||
class _ImageCache {
|
||||
static final Map<String, Widget> _cache = {};
|
||||
|
||||
static Widget? get(String key) => _cache[key];
|
||||
|
||||
static void put(String key, Widget widget) {
|
||||
if (_cache.length > 100) {
|
||||
// Limit cache size
|
||||
_cache.clear();
|
||||
}
|
||||
_cache[key] = widget;
|
||||
}
|
||||
}
|
||||
|
||||
class WoxImageView extends StatelessWidget {
|
||||
final WoxImage woxImage;
|
||||
final double? width;
|
||||
|
@ -18,8 +33,19 @@ class WoxImageView extends StatelessWidget {
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
// Create cache key based on image data and dimensions
|
||||
final cacheKey = '${woxImage.imageType}_${woxImage.imageData}_${width}_$height';
|
||||
|
||||
// Check cache first to prevent flickering
|
||||
final cachedWidget = _ImageCache.get(cacheKey);
|
||||
if (cachedWidget != null) {
|
||||
return cachedWidget;
|
||||
}
|
||||
|
||||
Widget imageWidget;
|
||||
|
||||
if (woxImage.imageType == WoxImageTypeEnum.WOX_IMAGE_TYPE_URL.code) {
|
||||
return Image.network(
|
||||
imageWidget = Image.network(
|
||||
woxImage.imageData,
|
||||
width: width,
|
||||
height: height,
|
||||
|
@ -31,26 +57,33 @@ class WoxImageView extends StatelessWidget {
|
|||
} else if (woxImage.imageType == WoxImageTypeEnum.WOX_IMAGE_TYPE_ABSOLUTE_PATH.code) {
|
||||
// check if file exists
|
||||
if (!File(woxImage.imageData).existsSync()) {
|
||||
return const SizedBox(width: 24, height: 24);
|
||||
imageWidget = const SizedBox(width: 24, height: 24);
|
||||
} else {
|
||||
imageWidget = Image.file(File(woxImage.imageData), width: width, height: height);
|
||||
}
|
||||
|
||||
return Image.file(File(woxImage.imageData), width: width, height: height);
|
||||
} else if (woxImage.imageType == WoxImageTypeEnum.WOX_IMAGE_TYPE_SVG.code) {
|
||||
return SvgPicture.string(woxImage.imageData, width: width, height: height);
|
||||
imageWidget = SvgPicture.string(woxImage.imageData, width: width, height: height);
|
||||
} else if (woxImage.imageType == WoxImageTypeEnum.WOX_IMAGE_TYPE_EMOJI.code) {
|
||||
return Text(woxImage.imageData, style: TextStyle(fontSize: width));
|
||||
imageWidget = Text(woxImage.imageData, style: TextStyle(fontSize: width));
|
||||
} else if (woxImage.imageType == WoxImageTypeEnum.WOX_IMAGE_TYPE_LOTTIE.code) {
|
||||
final bytes = utf8.encode(woxImage.imageData);
|
||||
return Lottie.memory(bytes, width: width, height: height);
|
||||
imageWidget = Lottie.memory(bytes, width: width, height: height);
|
||||
} else if (woxImage.imageType == WoxImageTypeEnum.WOX_IMAGE_TYPE_THEME.code) {
|
||||
return WoxThemeIconView(theme: WoxTheme.fromJson(jsonDecode(woxImage.imageData)), width: width, height: height);
|
||||
imageWidget = WoxThemeIconView(theme: WoxTheme.fromJson(jsonDecode(woxImage.imageData)), width: width, height: height);
|
||||
} else if (woxImage.imageType == WoxImageTypeEnum.WOX_IMAGE_TYPE_BASE64.code) {
|
||||
if (!woxImage.imageData.contains(";base64,")) {
|
||||
return Text("Invalid image data: ${woxImage.imageData}", style: const TextStyle(color: Colors.red));
|
||||
}
|
||||
imageWidget = Text("Invalid image data: ${woxImage.imageData}", style: const TextStyle(color: Colors.red));
|
||||
} else {
|
||||
final imageData = woxImage.imageData.split(";base64,")[1];
|
||||
return Image.memory(base64Decode(imageData), width: width, height: height, fit: BoxFit.contain);
|
||||
imageWidget = Image.memory(base64Decode(imageData), width: width, height: height, fit: BoxFit.contain);
|
||||
}
|
||||
return const SizedBox(width: 24, height: 24);
|
||||
} else {
|
||||
imageWidget = const SizedBox(width: 24, height: 24);
|
||||
}
|
||||
|
||||
// Cache the widget to prevent future rebuilds
|
||||
_ImageCache.put(cacheKey, imageWidget);
|
||||
|
||||
return imageWidget;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -57,9 +57,6 @@ class WoxListView<T> extends StatelessWidget {
|
|||
physics: const NeverScrollableScrollPhysics(),
|
||||
itemCount: controller.items.length,
|
||||
itemExtent: WoxThemeUtil.instance.getResultListViewHeightByCount(1),
|
||||
addAutomaticKeepAlives: false,
|
||||
addRepaintBoundaries: false,
|
||||
addSemanticIndexes: false,
|
||||
itemBuilder: (context, index) {
|
||||
var item = controller.items[index];
|
||||
return MouseRegion(
|
||||
|
|
|
@ -124,6 +124,14 @@ class WoxLauncherController extends GetxController {
|
|||
tag: 'action',
|
||||
);
|
||||
|
||||
// Add focus listener to query box
|
||||
queryBoxFocusNode.addListener(() {
|
||||
if (queryBoxFocusNode.hasFocus) {
|
||||
// Call API when query box gains focus
|
||||
WoxApi.instance.onQueryBoxFocus();
|
||||
}
|
||||
});
|
||||
|
||||
// Initialize doctor check info
|
||||
doctorCheckInfo.value = DoctorCheckInfo.empty();
|
||||
}
|
||||
|
@ -726,7 +734,6 @@ class WoxLauncherController extends GetxController {
|
|||
resizeHeight();
|
||||
}
|
||||
|
||||
// update actions list
|
||||
var actions = result.value.data.actions.map((e) => WoxListItem.fromResultAction(e)).toList();
|
||||
var oldActionIndex = actionListViewController.activeIndex.value;
|
||||
var oldActionCount = actionListViewController.items.length;
|
||||
|
|
Loading…
Reference in New Issue