mirror of
https://github.com/lollipopkit/flutter_server_box.git
synced 2025-12-19 08:14:21 +01:00
SFTP supports reversed sorting
This commit is contained in:
@@ -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});
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user