add: use DataTable for desktop file transfer
This commit is contained in:
parent
6b8fc6efe9
commit
e7a8bbd291
@ -118,8 +118,7 @@ class _FileManagerPageState extends State<FileManagerPage>
|
|||||||
PopupMenuItem(
|
PopupMenuItem(
|
||||||
child: Row(
|
child: Row(
|
||||||
children: [
|
children: [
|
||||||
Icon(Icons.folder_outlined,
|
Icon(Icons.folder_outlined, color: Colors.black),
|
||||||
color: Colors.black),
|
|
||||||
SizedBox(width: 5),
|
SizedBox(width: 5),
|
||||||
Text(translate("Create Folder"))
|
Text(translate("Create Folder"))
|
||||||
],
|
],
|
||||||
@ -150,16 +149,15 @@ class _FileManagerPageState extends State<FileManagerPage>
|
|||||||
model.toggleSelectMode();
|
model.toggleSelectMode();
|
||||||
} else if (v == "folder") {
|
} else if (v == "folder") {
|
||||||
final name = TextEditingController();
|
final name = TextEditingController();
|
||||||
DialogManager.show((setState, close) =>
|
DialogManager.show((setState, close) => CustomAlertDialog(
|
||||||
CustomAlertDialog(
|
|
||||||
title: Text(translate("Create Folder")),
|
title: Text(translate("Create Folder")),
|
||||||
content: Column(
|
content: Column(
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
children: [
|
children: [
|
||||||
TextFormField(
|
TextFormField(
|
||||||
decoration: InputDecoration(
|
decoration: InputDecoration(
|
||||||
labelText: translate(
|
labelText:
|
||||||
"Please enter the folder name"),
|
translate("Please enter the folder name"),
|
||||||
),
|
),
|
||||||
controller: name,
|
controller: name,
|
||||||
),
|
),
|
||||||
@ -192,120 +190,195 @@ class _FileManagerPageState extends State<FileManagerPage>
|
|||||||
Widget body({bool isLocal = false}) {
|
Widget body({bool isLocal = false}) {
|
||||||
final fd = isLocal ? model.currentLocalDir : model.currentRemoteDir;
|
final fd = isLocal ? model.currentLocalDir : model.currentRemoteDir;
|
||||||
final entries = fd.entries;
|
final entries = fd.entries;
|
||||||
return Column(children: [
|
return Container(
|
||||||
headTools(isLocal),
|
decoration: BoxDecoration(
|
||||||
Expanded(
|
color: Colors.white70, border: Border.all(color: Colors.grey)),
|
||||||
child: ListView.builder(
|
margin: const EdgeInsets.all(16.0),
|
||||||
itemCount: entries.length + 1,
|
padding: const EdgeInsets.all(8.0),
|
||||||
itemBuilder: (context, index) {
|
child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
|
||||||
if (index >= entries.length) {
|
headTools(isLocal),
|
||||||
return listTail(isLocal: isLocal);
|
Expanded(
|
||||||
}
|
child: Row(
|
||||||
var selected = false;
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
if (model.selectMode) {
|
children: [
|
||||||
selected = _selectedItems.contains(entries[index]);
|
Expanded(
|
||||||
}
|
child: SingleChildScrollView(
|
||||||
|
child: DataTable(
|
||||||
final sizeStr = entries[index].isFile
|
showCheckboxColumn: true,
|
||||||
? readableFileSize(entries[index].size.toDouble())
|
dataRowHeight: 30,
|
||||||
: "";
|
columnSpacing: 8,
|
||||||
return Card(
|
columns: [
|
||||||
child: ListTile(
|
DataColumn(label: Text(translate(" "))), // icon
|
||||||
leading: Icon(
|
DataColumn(
|
||||||
entries[index].isFile ? Icons.feed_outlined : Icons.folder,
|
label: Text(
|
||||||
size: 40),
|
translate("Name"),
|
||||||
title: Text(entries[index].name),
|
)),
|
||||||
selected: selected,
|
DataColumn(label: Text(translate("Modified"))),
|
||||||
subtitle: Text(
|
DataColumn(label: Text(translate("Size"))),
|
||||||
entries[index]
|
],
|
||||||
.lastModified()
|
rows: entries.map((entry) {
|
||||||
.toString()
|
final sizeStr = entry.isFile
|
||||||
.replaceAll(".000", "") +
|
? readableFileSize(entry.size.toDouble())
|
||||||
" " +
|
: "";
|
||||||
sizeStr,
|
return DataRow(
|
||||||
style: TextStyle(fontSize: 12, color: MyTheme.darkGray),
|
key: ValueKey(entry.name),
|
||||||
|
onSelectChanged: (s) {
|
||||||
|
// TODO
|
||||||
|
},
|
||||||
|
cells: [
|
||||||
|
// TODO: icon
|
||||||
|
DataCell(Icon(
|
||||||
|
entry.isFile ? Icons.feed_outlined : Icons.folder,
|
||||||
|
size: 25)),
|
||||||
|
DataCell(
|
||||||
|
ConstrainedBox(
|
||||||
|
constraints: BoxConstraints(maxWidth: 100),
|
||||||
|
child: Text(entry.name,
|
||||||
|
overflow: TextOverflow.ellipsis)),
|
||||||
|
onTap: () {
|
||||||
|
if (entry.isDirectory) {
|
||||||
|
model.openDirectory(entry.path, isLocal: isLocal);
|
||||||
|
} else {
|
||||||
|
// Perform file-related tasks.
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
DataCell(Text(
|
||||||
|
entry
|
||||||
|
.lastModified()
|
||||||
|
.toString()
|
||||||
|
.replaceAll(".000", "") +
|
||||||
|
" ",
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 12, color: MyTheme.darkGray),
|
||||||
|
)),
|
||||||
|
DataCell(Text(
|
||||||
|
sizeStr,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 12, color: MyTheme.darkGray),
|
||||||
|
)),
|
||||||
|
]);
|
||||||
|
}).toList(),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
trailing: needShowCheckBox()
|
)
|
||||||
? Checkbox(
|
],
|
||||||
value: selected,
|
)),
|
||||||
onChanged: (v) {
|
Center(child: listTail(isLocal: isLocal)),
|
||||||
if (v == null) return;
|
// Expanded(
|
||||||
if (v && !selected) {
|
// child: ListView.builder(
|
||||||
_selectedItems.add(isLocal, entries[index]);
|
// itemCount: entries.length + 1,
|
||||||
} else if (!v && selected) {
|
// itemBuilder: (context, index) {
|
||||||
_selectedItems.remove(entries[index]);
|
// if (index >= entries.length) {
|
||||||
}
|
// return listTail(isLocal: isLocal);
|
||||||
setState(() {});
|
// }
|
||||||
})
|
// var selected = false;
|
||||||
: PopupMenuButton<String>(
|
// if (model.selectMode) {
|
||||||
icon: Icon(Icons.more_vert),
|
// selected = _selectedItems.contains(entries[index]);
|
||||||
itemBuilder: (context) {
|
// }
|
||||||
return [
|
//
|
||||||
PopupMenuItem(
|
// final sizeStr = entries[index].isFile
|
||||||
child: Text(translate("Delete")),
|
// ? readableFileSize(entries[index].size.toDouble())
|
||||||
value: "delete",
|
// : "";
|
||||||
),
|
// return Card(
|
||||||
PopupMenuItem(
|
// child: ListTile(
|
||||||
child: Text(translate("Multi Select")),
|
// leading: Icon(
|
||||||
value: "multi_select",
|
// entries[index].isFile ? Icons.feed_outlined : Icons.folder,
|
||||||
),
|
// size: 40),
|
||||||
PopupMenuItem(
|
// title: Text(entries[index].name),
|
||||||
child: Text(translate("Properties")),
|
// selected: selected,
|
||||||
value: "properties",
|
// subtitle: Text(
|
||||||
enabled: false,
|
// entries[index]
|
||||||
)
|
// .lastModified()
|
||||||
];
|
// .toString()
|
||||||
},
|
// .replaceAll(".000", "") +
|
||||||
onSelected: (v) {
|
// " " +
|
||||||
if (v == "delete") {
|
// sizeStr,
|
||||||
final items = SelectedItems();
|
// style: TextStyle(fontSize: 12, color: MyTheme.darkGray),
|
||||||
items.add(isLocal, entries[index]);
|
// ),
|
||||||
model.removeAction(items);
|
// trailing: needShowCheckBox()
|
||||||
} else if (v == "multi_select") {
|
// ? Checkbox(
|
||||||
_selectedItems.clear();
|
// value: selected,
|
||||||
model.toggleSelectMode();
|
// onChanged: (v) {
|
||||||
}
|
// if (v == null) return;
|
||||||
}),
|
// if (v && !selected) {
|
||||||
onTap: () {
|
// _selectedItems.add(isLocal, entries[index]);
|
||||||
if (model.selectMode && !_selectedItems.isOtherPage(isLocal)) {
|
// } else if (!v && selected) {
|
||||||
if (selected) {
|
// _selectedItems.remove(entries[index]);
|
||||||
_selectedItems.remove(entries[index]);
|
// }
|
||||||
} else {
|
// setState(() {});
|
||||||
_selectedItems.add(isLocal, entries[index]);
|
// })
|
||||||
}
|
// : PopupMenuButton<String>(
|
||||||
setState(() {});
|
// icon: Icon(Icons.more_vert),
|
||||||
return;
|
// itemBuilder: (context) {
|
||||||
}
|
// return [
|
||||||
if (entries[index].isDirectory) {
|
// PopupMenuItem(
|
||||||
model.openDirectory(entries[index].path, isLocal: isLocal);
|
// child: Text(translate("Delete")),
|
||||||
breadCrumbScrollToEnd(isLocal);
|
// value: "delete",
|
||||||
} else {
|
// ),
|
||||||
// Perform file-related tasks.
|
// PopupMenuItem(
|
||||||
}
|
// child: Text(translate("Multi Select")),
|
||||||
},
|
// value: "multi_select",
|
||||||
onLongPress: () {
|
// ),
|
||||||
_selectedItems.clear();
|
// PopupMenuItem(
|
||||||
model.toggleSelectMode();
|
// child: Text(translate("Properties")),
|
||||||
if (model.selectMode) {
|
// value: "properties",
|
||||||
_selectedItems.add(isLocal, entries[index]);
|
// enabled: false,
|
||||||
}
|
// )
|
||||||
setState(() {});
|
// ];
|
||||||
},
|
// },
|
||||||
),
|
// onSelected: (v) {
|
||||||
);
|
// if (v == "delete") {
|
||||||
},
|
// final items = SelectedItems();
|
||||||
))
|
// items.add(isLocal, entries[index]);
|
||||||
]);
|
// model.removeAction(items);
|
||||||
|
// } else if (v == "multi_select") {
|
||||||
|
// _selectedItems.clear();
|
||||||
|
// model.toggleSelectMode();
|
||||||
|
// }
|
||||||
|
// }),
|
||||||
|
// onTap: () {
|
||||||
|
// if (model.selectMode && !_selectedItems.isOtherPage(isLocal)) {
|
||||||
|
// if (selected) {
|
||||||
|
// _selectedItems.remove(entries[index]);
|
||||||
|
// } else {
|
||||||
|
// _selectedItems.add(isLocal, entries[index]);
|
||||||
|
// }
|
||||||
|
// setState(() {});
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
// if (entries[index].isDirectory) {
|
||||||
|
// model.openDirectory(entries[index].path, isLocal: isLocal);
|
||||||
|
// breadCrumbScrollToEnd(isLocal);
|
||||||
|
// } else {
|
||||||
|
// // Perform file-related tasks.
|
||||||
|
// }
|
||||||
|
// },
|
||||||
|
// onLongPress: () {
|
||||||
|
// _selectedItems.clear();
|
||||||
|
// model.toggleSelectMode();
|
||||||
|
// if (model.selectMode) {
|
||||||
|
// _selectedItems.add(isLocal, entries[index]);
|
||||||
|
// }
|
||||||
|
// setState(() {});
|
||||||
|
// },
|
||||||
|
// ),
|
||||||
|
// );
|
||||||
|
// },
|
||||||
|
// ))
|
||||||
|
]),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// transfer status list
|
/// transfer status list
|
||||||
/// watch transfer status
|
/// watch transfer status
|
||||||
Widget statusList() {
|
Widget statusList() {
|
||||||
return PreferredSize(child: Container(
|
return PreferredSize(
|
||||||
decoration: BoxDecoration(
|
child: Container(
|
||||||
border: Border.all(color: Colors.white70)
|
margin: const EdgeInsets.only(top: 16.0,bottom: 16.0, right: 16.0),
|
||||||
),
|
padding: const EdgeInsets.all(8.0),
|
||||||
), preferredSize: Size(200, double.infinity));
|
decoration: BoxDecoration(color: Colors.white70,border: Border.all(color: Colors.grey)),
|
||||||
|
),
|
||||||
|
preferredSize: Size(200, double.infinity));
|
||||||
}
|
}
|
||||||
|
|
||||||
goBack({bool? isLocal}) {
|
goBack({bool? isLocal}) {
|
||||||
@ -313,10 +386,10 @@ class _FileManagerPageState extends State<FileManagerPage>
|
|||||||
}
|
}
|
||||||
|
|
||||||
breadCrumbScrollToEnd(bool isLocal) {
|
breadCrumbScrollToEnd(bool isLocal) {
|
||||||
final controller = isLocal ? _breadCrumbLocalScroller : _breadCrumbRemoteScroller;
|
final controller =
|
||||||
|
isLocal ? _breadCrumbLocalScroller : _breadCrumbRemoteScroller;
|
||||||
Future.delayed(Duration(milliseconds: 200), () {
|
Future.delayed(Duration(milliseconds: 200), () {
|
||||||
controller.animateTo(
|
controller.animateTo(controller.position.maxScrollExtent,
|
||||||
controller.position.maxScrollExtent,
|
|
||||||
duration: Duration(milliseconds: 200),
|
duration: Duration(milliseconds: 200),
|
||||||
curve: Curves.fastLinearToSlowEaseIn);
|
curve: Curves.fastLinearToSlowEaseIn);
|
||||||
});
|
});
|
||||||
@ -343,7 +416,10 @@ class _FileManagerPageState extends State<FileManagerPage>
|
|||||||
model.openDirectory(path, isLocal: isLocal);
|
model.openDirectory(path, isLocal: isLocal);
|
||||||
}, isLocal),
|
}, isLocal),
|
||||||
divider: Icon(Icons.chevron_right),
|
divider: Icon(Icons.chevron_right),
|
||||||
overflow: ScrollableOverflow(controller: isLocal ? _breadCrumbLocalScroller : _breadCrumbRemoteScroller),
|
overflow: ScrollableOverflow(
|
||||||
|
controller: isLocal
|
||||||
|
? _breadCrumbLocalScroller
|
||||||
|
: _breadCrumbRemoteScroller),
|
||||||
)),
|
)),
|
||||||
Row(
|
Row(
|
||||||
children: [
|
children: [
|
||||||
@ -478,8 +554,8 @@ class _FileManagerPageState extends State<FileManagerPage>
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
List<BreadCrumbItem> getPathBreadCrumbItems(
|
List<BreadCrumbItem> getPathBreadCrumbItems(void Function() onHome,
|
||||||
void Function() onHome, void Function(List<String>) onPressed, bool isLocal) {
|
void Function(List<String>) onPressed, bool isLocal) {
|
||||||
final path = model.shortPath(isLocal);
|
final path = model.shortPath(isLocal);
|
||||||
final list = PathUtil.split(path, model.currentIsWindows);
|
final list = PathUtil.split(path, model.currentIsWindows);
|
||||||
final breadCrumbList = [
|
final breadCrumbList = [
|
||||||
|
Loading…
x
Reference in New Issue
Block a user