SFTP supports reversed sorting

This commit is contained in:
PaperCube
2024-02-17 00:26:01 +00:00
parent 18b33ee0a2
commit 8d722da799

View File

@@ -10,6 +10,7 @@ import 'package:toolbox/core/extension/context/snackbar.dart';
import 'package:toolbox/core/extension/sftpfile.dart'; import 'package:toolbox/core/extension/sftpfile.dart';
import 'package:toolbox/core/utils/comparator.dart'; import 'package:toolbox/core/utils/comparator.dart';
import 'package:toolbox/core/utils/platform/base.dart'; import 'package:toolbox/core/utils/platform/base.dart';
import 'package:toolbox/data/res/color.dart';
import 'package:toolbox/data/res/logger.dart'; import 'package:toolbox/data/res/logger.dart';
import 'package:toolbox/data/res/misc.dart'; import 'package:toolbox/data/res/misc.dart';
import 'package:toolbox/data/res/provider.dart'; import 'package:toolbox/data/res/provider.dart';
@@ -51,7 +52,8 @@ class _SftpPageState extends State<SftpPage> with AfterLayoutMixin {
final _status = SftpBrowserStatus(); final _status = SftpBrowserStatus();
late final _client = widget.spi.server?.client; late final _client = widget.spi.server?.client;
final _sortType = ValueNotifier(_SortType.name); final _sortOption =
ValueNotifier(_SortOption(sortBy: _SortType.name, reversed: false));
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@@ -70,29 +72,47 @@ class _SftpPageState extends State<SftpPage> with AfterLayoutMixin {
icon: const Icon(Icons.downloading), icon: const Icon(Icons.downloading),
onPressed: () => AppRoute.sftpMission().go(context), onPressed: () => AppRoute.sftpMission().go(context),
), ),
ValueListenableBuilder<_SortType>( ValueListenableBuilder(
valueListenable: _sortType, valueListenable: _sortOption,
builder: (context, value, child) { builder: (context, value, child) {
return PopupMenuButton<_SortType>( return PopupMenuButton<_SortType>(
icon: const Icon(Icons.sort), icon: const Icon(Icons.sort),
itemBuilder: (context) { itemBuilder: (context) {
return [ final currentSelectedOption = _sortOption.value;
PopupMenuItem( final options = [
value: _SortType.name, (_SortType.name, l10n.name),
child: Text(l10n.name), (_SortType.size, l10n.size),
), (_SortType.time, l10n.time),
PopupMenuItem(
value: _SortType.size,
child: Text(l10n.size),
),
PopupMenuItem(
value: _SortType.time,
child: Text(l10n.time),
),
]; ];
return options.map((r) {
final (type, name) = r;
return PopupMenuItem(
value: type,
child: Text(
type == currentSelectedOption.sortBy
? "$name (${currentSelectedOption.reversed ? '-' : '+'})"
: name,
style: TextStyle(
color: type == currentSelectedOption.sortBy
? primaryColor
: null,
fontWeight: type == currentSelectedOption.sortBy
? FontWeight.bold
: null,
),
),
);
}).toList();
}, },
onSelected: (value) { onSelected: (sortBy) {
_sortType.value = value; final oldValue = _sortOption.value;
if (oldValue.sortBy == sortBy) {
_sortOption.value = _SortOption(
sortBy: sortBy, reversed: !oldValue.reversed);
} else {
_sortOption.value =
_SortOption(sortBy: sortBy, reversed: false);
}
}, },
); );
}, },
@@ -275,9 +295,10 @@ class _SftpPageState extends State<SftpPage> with AfterLayoutMixin {
child: FadeIn( child: FadeIn(
key: Key(widget.spi.name + _status.path!.path), key: Key(widget.spi.name + _status.path!.path),
child: ValueListenableBuilder( child: ValueListenableBuilder(
valueListenable: _sortType, valueListenable: _sortOption,
builder: (_, sortType, __) { builder: (_, sortOption, __) {
final files = sortType.sort(_status.files!); final files = sortOption.sortBy
.sort(_status.files!, reversed: sortOption.reversed);
return ListView.builder( return ListView.builder(
itemCount: files.length, itemCount: files.length,
padding: const EdgeInsets.symmetric(horizontal: 7, vertical: 3), padding: const EdgeInsets.symmetric(horizontal: 7, vertical: 3),
@@ -798,15 +819,17 @@ enum _SortType {
size, size,
; ;
List<SftpName> sort(List<SftpName> files) { List<SftpName> sort(List<SftpName> files, {bool reversed = false}) {
switch (this) { switch (this) {
case _SortType.name: case _SortType.name:
files.sort( files.sort(
ChainComparator<SftpName>.create() ChainComparator<SftpName>.create()
.thenTrueFirst((x) => x.attr.isDirectory) .thenTrueFirst((x) => x.attr.isDirectory)
.thenWithComparator((a, b) => .thenWithComparator(
Comparators.compareStringCaseInsensitive()( (a, b) => Comparators.compareStringCaseInsensitive()(
a.filename, b.filename)) a.filename, b.filename),
reversed: reversed,
)
.compare, .compare,
); );
break; break;
@@ -814,7 +837,10 @@ enum _SortType {
files.sort( files.sort(
ChainComparator<SftpName>.create() ChainComparator<SftpName>.create()
.thenTrueFirst((x) => x.attr.isDirectory) .thenTrueFirst((x) => x.attr.isDirectory)
.thenCompareBy<num>((x) => x.attr.modifyTime ?? 0) .thenCompareBy<num>(
(x) => x.attr.modifyTime ?? 0,
reversed: reversed,
)
.compare, .compare,
); );
break; break;
@@ -822,7 +848,10 @@ enum _SortType {
files.sort( files.sort(
ChainComparator<SftpName>.create() ChainComparator<SftpName>.create()
.thenTrueFirst((x) => x.attr.isDirectory) .thenTrueFirst((x) => x.attr.isDirectory)
.thenCompareBy<num>((x) => x.attr.size ?? 0) .thenCompareBy<num>(
(x) => x.attr.size ?? 0,
reversed: reversed,
)
.compare, .compare,
); );
break; break;
@@ -830,3 +859,10 @@ enum _SortType {
return files; return files;
} }
} }
class _SortOption {
final _SortType sortBy;
final bool reversed;
_SortOption({required this.sortBy, required this.reversed});
}