b02daf1448
- 文件管理器分页加载、排序偏好、桌面表头排序、移动端排序菜单、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。
108 lines
2.8 KiB
Dart
108 lines
2.8 KiB
Dart
import 'package:flutter/material.dart';
|
|
|
|
import '../../core/constants/sort_options.dart';
|
|
|
|
/// 文件列表表头(桌面端),支持点击排序
|
|
class FileListHeader extends StatelessWidget {
|
|
final bool showCheckbox;
|
|
final SortOption? currentSort;
|
|
final ValueChanged<SortOption>? onSort;
|
|
|
|
const FileListHeader({
|
|
super.key,
|
|
this.showCheckbox = false,
|
|
this.currentSort,
|
|
this.onSort,
|
|
});
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
final theme = Theme.of(context);
|
|
|
|
return Container(
|
|
padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 8),
|
|
decoration: BoxDecoration(
|
|
border: Border(
|
|
bottom: BorderSide(color: theme.dividerColor.withValues(alpha: 0.2)),
|
|
),
|
|
),
|
|
child: Row(
|
|
children: [
|
|
if (showCheckbox) const SizedBox(width: 40),
|
|
// 图标占位
|
|
const SizedBox(width: 36 + 16),
|
|
Expanded(
|
|
flex: 5,
|
|
child: _buildSortHeader(context, theme, SortField.name, '名称'),
|
|
),
|
|
Expanded(
|
|
flex: 2,
|
|
child: _buildSortHeader(
|
|
context,
|
|
theme,
|
|
SortField.updatedAt,
|
|
'修改日期',
|
|
),
|
|
),
|
|
Expanded(
|
|
flex: 1,
|
|
child: _buildSortHeader(context, theme, SortField.size, '大小'),
|
|
),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
|
|
Widget _buildSortHeader(
|
|
BuildContext context,
|
|
ThemeData theme,
|
|
SortField field,
|
|
String label,
|
|
) {
|
|
final isActive = currentSort?.field == field;
|
|
final style = TextStyle(
|
|
color: isActive ? theme.colorScheme.primary : theme.hintColor,
|
|
fontSize: 12,
|
|
fontWeight: isActive ? FontWeight.w600 : FontWeight.w500,
|
|
);
|
|
|
|
return InkWell(
|
|
onTap: () => _onHeaderTap(field),
|
|
borderRadius: BorderRadius.circular(4),
|
|
child: Padding(
|
|
padding: const EdgeInsets.symmetric(vertical: 2),
|
|
child: Row(
|
|
mainAxisSize: MainAxisSize.min,
|
|
children: [
|
|
Text(label, style: style),
|
|
if (isActive) ...[
|
|
const SizedBox(width: 4),
|
|
Icon(
|
|
currentSort!.direction == SortDirection.asc
|
|
? Icons.arrow_upward
|
|
: Icons.arrow_downward,
|
|
size: 14,
|
|
color: theme.colorScheme.primary,
|
|
),
|
|
],
|
|
],
|
|
),
|
|
),
|
|
);
|
|
}
|
|
|
|
void _onHeaderTap(SortField field) {
|
|
if (onSort == null) return;
|
|
if (currentSort?.field == field) {
|
|
// 同一列:切换方向
|
|
final newDir = currentSort!.direction == SortDirection.asc
|
|
? SortDirection.desc
|
|
: SortDirection.asc;
|
|
onSort!(SortOption(field, newDir));
|
|
} else {
|
|
// 新列:默认升序
|
|
onSort!(SortOption(field, SortDirection.asc));
|
|
}
|
|
}
|
|
}
|