主要合入内容:

- 文件管理器分页加载、排序偏好、桌面表头排序、移动端排序菜单、Ctrl/Cmd+F搜索、Esc 关闭搜索、鼠标右滑返回上级。
- 移动端同步状态页、同步统计卡片、同步任务/累计统计事件、同步页布局更新。
- Android 相册同步默认路径改为 DCIM/Camera,下载路径改用 external_path。
- Rust sync-core 更新:Android 日志依赖、AlbumUpload/AlbumDownload、MirrorWcf 统计修复、Linux FUSE镜像挂载与读写同步支持。

- 依赖更新:external_path、fl_chart、pdfrx 升级,并修了 pdfrx 新版本的deprecated API。
- 新增文件包括:sort_options.dart、sync_page_android.dart、sync_stats_card.dart、platform/fuse.rs、sync_engine/fuse.rs。
This commit is contained in:
2026-06-04 07:11:43 +08:00
parent 5ee6ba1e28
commit b02daf1448
56 changed files with 7589 additions and 1200 deletions
+41 -20
View File
@@ -1,6 +1,7 @@
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:lucide_icons/lucide_icons.dart';
import 'package:provider/provider.dart';
@@ -18,7 +19,12 @@ import 'glassmorphism_container.dart';
class SearchDialog extends StatefulWidget {
const SearchDialog({super.key});
static bool _isShowing = false;
static bool get isShowing => _isShowing;
static Future<void> show(BuildContext context) {
if (_isShowing) return Future.value();
_isShowing = true;
return showGeneralDialog(
context: context,
barrierDismissible: true,
@@ -41,7 +47,7 @@ class SearchDialog extends StatefulWidget {
},
pageBuilder: (context, animation, secondaryAnimation) =>
const SearchDialog(),
);
).whenComplete(() => _isShowing = false);
}
@override
@@ -185,25 +191,40 @@ class _SearchDialogState extends State<SearchDialog> {
final isWide = screenWidth >= 600;
final dialogWidth = isWide ? 560.0 : screenWidth - 32.0;
return Center(
child: Container(
width: dialogWidth,
constraints: BoxConstraints(maxHeight: screenHeight * 0.75),
child: GlassmorphismContainer(
borderRadius: 16,
sigmaX: 20,
sigmaY: 20,
child: ClipRRect(
borderRadius: BorderRadius.circular(16),
child: Material(
color: Colors.transparent,
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
_buildSearchInput(context),
const Divider(height: 1),
Flexible(child: _buildBody(context)),
],
return Shortcuts(
shortcuts: <ShortcutActivator, Intent>{
const SingleActivator(LogicalKeyboardKey.escape): DismissIntent(),
},
child: Actions(
actions: <Type, Action<Intent>>{
DismissIntent: CallbackAction<DismissIntent>(
onInvoke: (_) {
Navigator.of(context).pop();
return null;
},
),
},
child: Center(
child: Container(
width: dialogWidth,
constraints: BoxConstraints(maxHeight: screenHeight * 0.75),
child: GlassmorphismContainer(
borderRadius: 16,
sigmaX: 20,
sigmaY: 20,
child: ClipRRect(
borderRadius: BorderRadius.circular(16),
child: Material(
color: Colors.transparent,
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
_buildSearchInput(context),
const Divider(height: 1),
Flexible(child: _buildBody(context)),
],
),
),
),
),
),