opt.: file view (#249)
This commit is contained in:
@@ -132,7 +132,7 @@ class _ServerEditPageState extends State<ServerEditPage> {
|
||||
() => delScripts = !delScripts,
|
||||
),
|
||||
controlAffinity: ListTileControlAffinity.leading,
|
||||
subtitle: Text(l10n.deleteScripts),
|
||||
title: Text(l10n.deleteScripts),
|
||||
tileColor: Colors.transparent,
|
||||
contentPadding: EdgeInsets.zero,
|
||||
)
|
||||
@@ -142,13 +142,15 @@ class _ServerEditPageState extends State<ServerEditPage> {
|
||||
actions: [
|
||||
TextButton(
|
||||
onPressed: () async {
|
||||
context.pop();
|
||||
if (delScripts) {
|
||||
context.showLoadingDialog();
|
||||
const cmd =
|
||||
'rm ${ShellFunc.srvBoxDir}/mobile_v*.sh';
|
||||
await widget.spi?.server?.client?.run(cmd);
|
||||
context.pop();
|
||||
}
|
||||
Pros.server.delServer(widget.spi!.id);
|
||||
context.pop();
|
||||
context.pop(true);
|
||||
},
|
||||
child: Text(l10n.ok, style: UIs.textRed),
|
||||
|
||||
@@ -39,6 +39,8 @@ class LocalStoragePage extends StatefulWidget {
|
||||
class _LocalStoragePageState extends State<LocalStoragePage> {
|
||||
LocalPath? _path;
|
||||
|
||||
final _sortType = ValueNotifier(_SortType.name);
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
@@ -73,12 +75,44 @@ class _LocalStoragePageState extends State<LocalStoragePage> {
|
||||
IconButton(
|
||||
icon: const Icon(Icons.downloading),
|
||||
onPressed: () => AppRoute.sftpMission().go(context),
|
||||
)
|
||||
),
|
||||
ValueListenableBuilder<_SortType>(
|
||||
valueListenable: _sortType,
|
||||
builder: (context, value, child) {
|
||||
return PopupMenuButton<_SortType>(
|
||||
icon: const Icon(Icons.sort),
|
||||
itemBuilder: (context) {
|
||||
return [
|
||||
PopupMenuItem(
|
||||
value: _SortType.name,
|
||||
child: Text(l10n.name),
|
||||
),
|
||||
PopupMenuItem(
|
||||
value: _SortType.size,
|
||||
child: Text(l10n.size),
|
||||
),
|
||||
PopupMenuItem(
|
||||
value: _SortType.time,
|
||||
child: Text(l10n.time),
|
||||
),
|
||||
];
|
||||
},
|
||||
onSelected: (value) {
|
||||
_sortType.value = value;
|
||||
},
|
||||
);
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
body: FadeIn(
|
||||
key: UniqueKey(),
|
||||
child: _buildBody(),
|
||||
child: ValueListenableBuilder(
|
||||
valueListenable: _sortType,
|
||||
builder: (_, val, __) {
|
||||
return _buildBody();
|
||||
},
|
||||
),
|
||||
),
|
||||
bottomNavigationBar: SafeArea(child: _buildPath()),
|
||||
);
|
||||
@@ -129,7 +163,8 @@ class _LocalStoragePageState extends State<LocalStoragePage> {
|
||||
);
|
||||
}
|
||||
final dir = Directory(_path!.path);
|
||||
final files = dir.listSync();
|
||||
final tempFiles = dir.listSync();
|
||||
final files = _sortType.value.sort(tempFiles);
|
||||
return ListView.builder(
|
||||
itemCount: files.length,
|
||||
padding: const EdgeInsets.symmetric(vertical: 3, horizontal: 7),
|
||||
@@ -142,7 +177,7 @@ class _LocalStoragePageState extends State<LocalStoragePage> {
|
||||
return CardX(
|
||||
child: ListTile(
|
||||
leading: isDir
|
||||
? const Icon(Icons.folder)
|
||||
? const Icon(Icons.folder_open)
|
||||
: const Icon(Icons.insert_drive_file),
|
||||
title: Text(fileName),
|
||||
subtitle: isDir
|
||||
@@ -350,3 +385,26 @@ class _LocalStoragePageState extends State<LocalStoragePage> {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
enum _SortType {
|
||||
name,
|
||||
size,
|
||||
time,
|
||||
;
|
||||
|
||||
List<FileSystemEntity> sort(List<FileSystemEntity> files) {
|
||||
switch (this) {
|
||||
case _SortType.name:
|
||||
files.sort((a, b) => a.path.compareTo(b.path));
|
||||
break;
|
||||
case _SortType.size:
|
||||
files.sort((a, b) => a.statSync().size.compareTo(b.statSync().size));
|
||||
break;
|
||||
case _SortType.time:
|
||||
files.sort(
|
||||
(a, b) => a.statSync().modified.compareTo(b.statSync().modified));
|
||||
break;
|
||||
}
|
||||
return files;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,6 +50,8 @@ class _SftpPageState extends State<SftpPage> with AfterLayoutMixin {
|
||||
final _status = SftpBrowserStatus();
|
||||
late final _client = widget.spi.server?.client;
|
||||
|
||||
final _sortType = ValueNotifier(_SortType.name);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
@@ -67,6 +69,33 @@ class _SftpPageState extends State<SftpPage> with AfterLayoutMixin {
|
||||
icon: const Icon(Icons.downloading),
|
||||
onPressed: () => AppRoute.sftpMission().go(context),
|
||||
),
|
||||
ValueListenableBuilder<_SortType>(
|
||||
valueListenable: _sortType,
|
||||
builder: (context, value, child) {
|
||||
return PopupMenuButton<_SortType>(
|
||||
icon: const Icon(Icons.sort),
|
||||
itemBuilder: (context) {
|
||||
return [
|
||||
PopupMenuItem(
|
||||
value: _SortType.name,
|
||||
child: Text(l10n.name),
|
||||
),
|
||||
PopupMenuItem(
|
||||
value: _SortType.size,
|
||||
child: Text(l10n.size),
|
||||
),
|
||||
PopupMenuItem(
|
||||
value: _SortType.time,
|
||||
child: Text(l10n.time),
|
||||
),
|
||||
];
|
||||
},
|
||||
onSelected: (value) {
|
||||
_sortType.value = value;
|
||||
},
|
||||
);
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
body: _buildFileView(),
|
||||
@@ -244,10 +273,16 @@ class _SftpPageState extends State<SftpPage> with AfterLayoutMixin {
|
||||
return RefreshIndicator(
|
||||
child: FadeIn(
|
||||
key: Key(widget.spi.name + _status.path!.path),
|
||||
child: ListView.builder(
|
||||
itemCount: _status.files!.length,
|
||||
padding: const EdgeInsets.symmetric(horizontal: 7, vertical: 3),
|
||||
itemBuilder: (_, index) => _buildItem(_status.files![index]),
|
||||
child: ValueListenableBuilder(
|
||||
valueListenable: _sortType,
|
||||
builder: (_, sortType, __) {
|
||||
final files = sortType.sort(_status.files!);
|
||||
return ListView.builder(
|
||||
itemCount: files.length,
|
||||
padding: const EdgeInsets.symmetric(horizontal: 7, vertical: 3),
|
||||
itemBuilder: (_, index) => _buildItem(files[index]),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
onRefresh: () => _listDir(),
|
||||
@@ -263,7 +298,7 @@ class _SftpPageState extends State<SftpPage> with AfterLayoutMixin {
|
||||
);
|
||||
return CardX(
|
||||
child: ListTile(
|
||||
leading: Icon(isDir ? Icons.folder : Icons.insert_drive_file),
|
||||
leading: Icon(isDir ? Icons.folder_outlined : Icons.insert_drive_file),
|
||||
title: Text(file.filename),
|
||||
trailing: trailing,
|
||||
subtitle: isDir
|
||||
@@ -755,3 +790,27 @@ String _getTime(int? unixMill) {
|
||||
.toString()
|
||||
.replaceFirst('.000', '');
|
||||
}
|
||||
|
||||
enum _SortType {
|
||||
name,
|
||||
time,
|
||||
size,
|
||||
;
|
||||
|
||||
List<SftpName> sort(List<SftpName> files) {
|
||||
switch (this) {
|
||||
case _SortType.name:
|
||||
files.sort((a, b) => a.filename.compareTo(b.filename));
|
||||
break;
|
||||
case _SortType.time:
|
||||
files.sort(
|
||||
(a, b) => (a.attr.modifyTime ?? 0).compareTo(b.attr.modifyTime ?? 0),
|
||||
);
|
||||
break;
|
||||
case _SortType.size:
|
||||
files.sort((a, b) => (a.attr.size ?? 0).compareTo(b.attr.size ?? 0));
|
||||
break;
|
||||
}
|
||||
return files;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user