refactor Desktop file_manager_page.dart

This commit is contained in:
csf 2023-03-08 22:32:55 +09:00
parent 2dd4545be0
commit d867decd98
2 changed files with 257 additions and 266 deletions

View File

@ -69,6 +69,7 @@ class _FileManagerPageState extends State<FileManagerPage>
late FFI _ffi;
FileModel get model => _ffi.fileModel;
JobController get jobController => model.jobController;
@override
void initState() {
@ -84,7 +85,6 @@ class _FileManagerPageState extends State<FileManagerPage>
Wakelock.enable();
}
debugPrint("File manager page init success with id ${widget.id}");
model.onDirChanged = breadCrumbScrollToEnd;
_ffi.dialogManager.setOverlayState(_overlayKeyState);
}
@ -107,31 +107,24 @@ class _FileManagerPageState extends State<FileManagerPage>
@override
Widget build(BuildContext context) {
super.build(context);
// TODO
final localController = FileController(isLocal: true);
final remoteController = FileController(isLocal: false);
return Overlay(key: _overlayKeyState.key, initialEntries: [
OverlayEntry(builder: (_) {
return ChangeNotifierProvider.value(
value: _ffi.fileModel,
child: Consumer<FileModel>(builder: (context, model, child) {
return Scaffold(
backgroundColor: Theme.of(context).scaffoldBackgroundColor,
body: Row(
children: [
Flexible(
flex: 3,
child: dropArea(FileManagerView(
localController, _ffi, _mouseFocusScope))),
Flexible(
flex: 3,
child: dropArea(FileManagerView(
remoteController, _ffi, _mouseFocusScope))),
Flexible(flex: 2, child: statusList())
],
),
);
}));
return Scaffold(
backgroundColor: Theme.of(context).scaffoldBackgroundColor,
body: Row(
children: [
Flexible(
flex: 3,
child: dropArea(FileManagerView(
model.localController, _ffi, _mouseFocusScope))),
Flexible(
flex: 3,
child: dropArea(FileManagerView(
model.remoteController, _ffi, _mouseFocusScope))),
Flexible(flex: 2, child: statusList())
],
),
);
})
]);
}
@ -169,7 +162,7 @@ class _FileManagerPageState extends State<FileManagerPage>
child: Container(
margin: const EdgeInsets.only(top: 16.0, bottom: 16.0, right: 16.0),
padding: const EdgeInsets.all(8.0),
child: model.jobTable.isEmpty
child: jobController.jobTable.isEmpty
? generateCard(
Center(
child: Column(
@ -195,7 +188,7 @@ class _FileManagerPageState extends State<FileManagerPage>
() => ListView.builder(
controller: ScrollController(),
itemBuilder: (BuildContext context, int index) {
final item = model.jobTable[index];
final item = jobController.jobTable[index];
return Padding(
padding: const EdgeInsets.only(bottom: 5),
child: generateCard(
@ -206,7 +199,7 @@ class _FileManagerPageState extends State<FileManagerPage>
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Transform.rotate(
angle: item.isRemote ? pi : 0,
angle: item.isRemoteToLocal ? pi : 0,
child: SvgPicture.asset(
"assets/arrow.svg",
color: Theme.of(context)
@ -293,7 +286,7 @@ class _FileManagerPageState extends State<FileManagerPage>
offstage: item.state != JobState.paused,
child: MenuButton(
onPressed: () {
model.resumeJob(item.id);
jobController.resumeJob(item.id);
},
child: SvgPicture.asset(
"assets/refresh.svg",
@ -310,8 +303,8 @@ class _FileManagerPageState extends State<FileManagerPage>
color: Colors.white,
),
onPressed: () {
model.jobTable.removeAt(index);
model.cancelJob(item.id);
jobController.jobTable.removeAt(index);
jobController.cancelJob(item.id);
},
color: MyTheme.accent,
hoverColor: MyTheme.accent80,
@ -325,7 +318,7 @@ class _FileManagerPageState extends State<FileManagerPage>
),
);
},
itemCount: model.jobTable.length,
itemCount: jobController.jobTable.length,
),
),
),
@ -337,18 +330,15 @@ class _FileManagerPageState extends State<FileManagerPage>
// ignore local
return;
}
var items = SelectedItems();
final items = SelectedItems(isLocal: false);
for (var file in details.files) {
final f = File(file.path);
items.add(
true,
Entry()
..path = file.path
..name = file.name
..size =
FileSystemEntity.isDirectorySync(f.path) ? 0 : f.lengthSync());
items.add(Entry()
..path = file.path
..name = file.name
..size = FileSystemEntity.isDirectorySync(f.path) ? 0 : f.lengthSync());
}
model.sendFiles(items, isRemote: false);
model.remoteController.sendFiles(items);
}
}
@ -364,7 +354,6 @@ class FileManagerView extends StatefulWidget {
}
class _FileManagerViewState extends State<FileManagerView> {
final _selectedItems = SelectedItems();
final _locationStatus = LocationStatus.bread.obs;
final _locationNode = FocusNode();
final _locationBarKey = GlobalKey();
@ -376,6 +365,8 @@ class _FileManagerViewState extends State<FileManagerView> {
final _modifiedColWidth = kDesktopFileTransferModifiedColWidth.obs;
final _fileListScrollController = ScrollController();
late final _selectedItems = SelectedItems(isLocal: isLocal);
/// [_lastClickTime], [_lastClickEntry] help to handle double click
var _lastClickTime =
DateTime.now().millisecondsSinceEpoch - bind.getDoubleClickTime() - 1000;
@ -390,6 +381,7 @@ class _FileManagerViewState extends State<FileManagerView> {
super.initState();
// register location listener
_locationNode.addListener(onLocationFocusChanged);
controller.directory.listen((e) => breadCrumbScrollToEnd());
}
@override
@ -508,7 +500,7 @@ class _FileManagerViewState extends State<FileManagerView> {
hoverColor: Theme.of(context).hoverColor,
onPressed: () {
_selectedItems.clear();
model.goBack(isLocal: isLocal);
controller.goBack();
},
),
MenuButton(
@ -523,7 +515,7 @@ class _FileManagerViewState extends State<FileManagerView> {
hoverColor: Theme.of(context).hoverColor,
onPressed: () {
_selectedItems.clear();
model.goToParentDirectory(isLocal: isLocal);
controller.goToParentDirectory();
},
),
],
@ -560,8 +552,8 @@ class _FileManagerViewState extends State<FileManagerView> {
Expanded(
child: _locationStatus.value ==
LocationStatus.bread
? buildBread(isLocal)
: buildPathLocation(isLocal)),
? buildBread()
: buildPathLocation()),
],
),
),
@ -617,7 +609,7 @@ class _FileManagerViewState extends State<FileManagerView> {
left: 3,
),
onPressed: () {
model.refresh(isLocal: isLocal);
controller.refresh();
},
child: SvgPicture.asset(
"assets/refresh.svg",
@ -641,7 +633,7 @@ class _FileManagerViewState extends State<FileManagerView> {
right: 3,
),
onPressed: () {
model.goHome(isLocal: isLocal);
controller.goToHomeDirectory();
},
child: SvgPicture.asset(
"assets/home.svg",
@ -656,12 +648,11 @@ class _FileManagerViewState extends State<FileManagerView> {
_ffi.dialogManager.show((setState, close) {
submit() {
if (name.value.text.isNotEmpty) {
model.createDir(
PathUtil.join(
model.getCurrentDir(isLocal).path,
name.value.text,
model.getCurrentIsWindows(isLocal)),
isLocal: isLocal);
controller.createDir(PathUtil.join(
controller.directory.value.path,
name.value.text,
controller.options.value.isWindows,
));
close();
}
}
@ -722,8 +713,7 @@ class _FileManagerViewState extends State<FileManagerView> {
MenuButton(
onPressed: validItems(_selectedItems)
? () async {
await (model.removeAction(_selectedItems,
isLocal: isLocal));
await (controller.removeAction(_selectedItems));
_selectedItems.clear();
}
: null,
@ -751,7 +741,7 @@ class _FileManagerViewState extends State<FileManagerView> {
),
onPressed: validItems(_selectedItems)
? () {
model.sendFiles(_selectedItems, isRemote: !isLocal);
controller.sendFiles(_selectedItems);
_selectedItems.clear();
}
: null,
@ -814,10 +804,10 @@ class _FileManagerViewState extends State<FileManagerView> {
switchType: SwitchType.scheckbox,
text: translate("Show Hidden Files"),
getter: () async {
return model.getCurrentShowHidden(isLocal);
return controller.options.value.isWindows;
},
setter: (bool v) async {
model.toggleShowHidden(local: isLocal);
controller.toggleShowHidden();
},
padding: kDesktopMenuPadding,
dismissOnClicked: true,
@ -825,7 +815,7 @@ class _FileManagerViewState extends State<FileManagerView> {
MenuEntryButton(
childBuilder: (style) => Text(translate("Select All"), style: style),
proc: () => setState(() =>
_selectedItems.selectAll(model.getCurrentDir(isLocal).entries)),
_selectedItems.selectAll(controller.directory.value.entries)),
padding: kDesktopMenuPadding,
dismissOnClicked: true),
MenuEntryButton(
@ -872,7 +862,7 @@ class _FileManagerViewState extends State<FileManagerView> {
Widget _buildFileList(
BuildContext context, bool isLocal, ScrollController scrollController) {
final fd = model.getCurrentDir(isLocal);
final fd = controller.directory.value;
final entries = fd.entries;
return ListSearchActionListener(
@ -919,161 +909,155 @@ class _FileManagerViewState extends State<FileManagerView> {
_jumpToEntry(isLocal, searchResult.first, scrollController,
kDesktopFileTransferRowHeight);
},
child: ObxValue<RxString>(
(searchText) {
final filteredEntries = searchText.isNotEmpty
? entries.where((element) {
return element.name.contains(searchText.value);
}).toList(growable: false)
: entries;
final rows = filteredEntries.map((entry) {
final sizeStr =
entry.isFile ? readableFileSize(entry.size.toDouble()) : "";
final lastModifiedStr = entry.isDrive
? " "
: "${entry.lastModified().toString().replaceAll(".000", "")} ";
final isSelected = _selectedItems.contains(entry);
return Padding(
padding: EdgeInsets.symmetric(vertical: 1),
child: Container(
decoration: BoxDecoration(
color: isSelected
? Theme.of(context).hoverColor
: Theme.of(context).cardColor,
borderRadius: BorderRadius.all(
Radius.circular(5.0),
),
child: Obx(() {
final entries = controller.directory.value.entries;
final filteredEntries = _searchText.isNotEmpty
? entries.where((element) {
return element.name.contains(_searchText.value);
}).toList(growable: false)
: entries;
final rows = filteredEntries.map((entry) {
final sizeStr =
entry.isFile ? readableFileSize(entry.size.toDouble()) : "";
final lastModifiedStr = entry.isDrive
? " "
: "${entry.lastModified().toString().replaceAll(".000", "")} ";
final isSelected = _selectedItems.contains(entry);
return Padding(
padding: EdgeInsets.symmetric(vertical: 1),
child: Container(
decoration: BoxDecoration(
color: isSelected
? Theme.of(context).hoverColor
: Theme.of(context).cardColor,
borderRadius: BorderRadius.all(
Radius.circular(5.0),
),
key: ValueKey(entry.name),
height: kDesktopFileTransferRowHeight,
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
Expanded(
child: InkWell(
child: Row(
children: [
GestureDetector(
child: Obx(
() => Container(
width: _nameColWidth.value,
child: Tooltip(
waitDuration:
Duration(milliseconds: 500),
message: entry.name,
child: Row(children: [
entry.isDrive
? Image(
image: iconHardDrive,
fit: BoxFit.scaleDown,
color: Theme.of(context)
.iconTheme
.color
?.withOpacity(0.7))
.paddingAll(4)
: SvgPicture.asset(
entry.isFile
? "assets/file.svg"
: "assets/folder.svg",
color: Theme.of(context)
.tabBarTheme
.labelColor,
),
Expanded(
child: Text(
entry.name.nonBreaking,
overflow:
TextOverflow.ellipsis))
]),
),
key: ValueKey(entry.name),
height: kDesktopFileTransferRowHeight,
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
Expanded(
child: InkWell(
child: Row(
children: [
GestureDetector(
child: Obx(
() => Container(
width: _nameColWidth.value,
child: Tooltip(
waitDuration: Duration(milliseconds: 500),
message: entry.name,
child: Row(children: [
entry.isDrive
? Image(
image: iconHardDrive,
fit: BoxFit.scaleDown,
color: Theme.of(context)
.iconTheme
.color
?.withOpacity(0.7))
.paddingAll(4)
: SvgPicture.asset(
entry.isFile
? "assets/file.svg"
: "assets/folder.svg",
color: Theme.of(context)
.tabBarTheme
.labelColor,
),
Expanded(
child: Text(entry.name.nonBreaking,
overflow:
TextOverflow.ellipsis))
]),
)),
),
onTap: () {
final items = _selectedItems;
// handle double click
if (_checkDoubleClick(entry)) {
controller.openDirectory(entry.path);
items.clear();
return;
}
_onSelectedChanged(
items, filteredEntries, entry, isLocal);
},
),
SizedBox(
width: 2.0,
),
GestureDetector(
child: Obx(
() => SizedBox(
width: _modifiedColWidth.value,
child: Tooltip(
waitDuration: Duration(milliseconds: 500),
message: lastModifiedStr,
child: Text(
lastModifiedStr,
overflow: TextOverflow.ellipsis,
style: TextStyle(
fontSize: 12,
color: MyTheme.darkGray,
),
)),
),
onTap: () {
final items = _selectedItems;
// handle double click
if (_checkDoubleClick(entry)) {
openDirectory(entry.path, isLocal: isLocal);
items.clear();
return;
}
_onSelectedChanged(
items, filteredEntries, entry, isLocal);
},
),
SizedBox(
width: 2.0,
),
GestureDetector(
child: Obx(
() => SizedBox(
width: _modifiedColWidth.value,
child: Tooltip(
waitDuration:
Duration(milliseconds: 500),
message: lastModifiedStr,
child: Text(
lastModifiedStr,
overflow: TextOverflow.ellipsis,
style: TextStyle(
fontSize: 12,
color: MyTheme.darkGray,
),
)),
),
// Divider from header.
SizedBox(
width: 2.0,
),
Expanded(
// width: 100,
child: GestureDetector(
child: Tooltip(
waitDuration: Duration(milliseconds: 500),
message: sizeStr,
child: Text(
sizeStr,
overflow: TextOverflow.ellipsis,
style: TextStyle(
fontSize: 10, color: MyTheme.darkGray),
),
),
),
// Divider from header.
SizedBox(
width: 2.0,
),
Expanded(
// width: 100,
child: GestureDetector(
child: Tooltip(
waitDuration: Duration(milliseconds: 500),
message: sizeStr,
child: Text(
sizeStr,
overflow: TextOverflow.ellipsis,
style: TextStyle(
fontSize: 10,
color: MyTheme.darkGray),
),
),
),
),
],
),
),
],
),
),
],
)),
);
}).toList(growable: false);
return Column(
children: [
// Header
Row(
children: [
Expanded(child: _buildFileBrowserHeader(context, isLocal)),
],
),
// Body
Expanded(
child: ListView.builder(
controller: scrollController,
itemExtent: kDesktopFileTransferRowHeight,
itemBuilder: (context, index) {
return rows[index];
},
itemCount: rows.length,
),
),
],
),
],
)),
);
},
_searchText,
),
}).toList(growable: false);
return Column(
children: [
// Header
Row(
children: [
Expanded(child: _buildFileBrowserHeader(context, isLocal)),
],
),
// Body
Expanded(
child: ListView.builder(
controller: scrollController,
itemExtent: kDesktopFileTransferRowHeight,
itemBuilder: (context, index) {
return rows[index];
},
itemCount: rows.length,
),
),
],
);
}),
);
}
@ -1084,7 +1068,7 @@ class _FileManagerViewState extends State<FileManagerView> {
void _jumpToEntry(bool isLocal, Entry entry,
ScrollController scrollController, double rowHeight) {
final entries = model.getCurrentDir(isLocal).entries;
final entries = controller.directory.value.entries;
final index = entries.indexOf(entry);
if (index == -1) {
debugPrint("entry is not valid: ${entry.path}");
@ -1101,7 +1085,7 @@ class _FileManagerViewState extends State<FileManagerView> {
scrollController.position.maxScrollExtent);
scrollController.jumpTo(offset);
setState(() {
selectedEntries.add(isLocal, searchResult.first);
selectedEntries.add(searchResult.first);
debugPrint("focused on ${searchResult.first.name}");
});
}
@ -1116,7 +1100,7 @@ class _FileManagerViewState extends State<FileManagerView> {
if (selectedItems.contains(entry)) {
selectedItems.remove(entry);
} else {
selectedItems.add(isLocal, entry);
selectedItems.add(entry);
}
} else if (isShiftDown) {
final List<int> indexGroup = [];
@ -1130,10 +1114,10 @@ class _FileManagerViewState extends State<FileManagerView> {
selectedItems.clear();
entries
.getRange(minIndex, maxIndex + 1)
.forEach((e) => selectedItems.add(isLocal, e));
.forEach((e) => selectedItems.add(e));
} else {
selectedItems.clear();
selectedItems.add(isLocal, entry);
selectedItems.add(entry);
}
setState(() {});
}
@ -1205,7 +1189,7 @@ class _FileManagerViewState extends State<FileManagerView> {
} else {
ascending.value = !ascending.value!;
}
model.changeSortStyle(sortBy,
controller.changeSortStyle(sortBy,
isLocal: isLocal, ascending: ascending.value!);
},
child: SizedBox(
@ -1234,21 +1218,21 @@ class _FileManagerViewState extends State<FileManagerView> {
),
),
), () {
if (model.getSortStyle(isLocal) == sortBy) {
return model.getSortAscending(isLocal).obs;
if (controller.sortBy.value == sortBy) {
return controller.sortAscending;
} else {
return Rx<bool?>(null);
}
}());
}
Widget buildBread(bool isLocal) {
Widget buildBread() {
final items = getPathBreadCrumbItems(isLocal, (list) {
var path = "";
for (var item in list) {
path = PathUtil.join(path, item, model.getCurrentIsWindows(isLocal));
path = PathUtil.join(path, item, controller.options.value.isWindows);
}
openDirectory(path, isLocal: isLocal);
controller.openDirectory(path);
});
return items.isEmpty
@ -1290,7 +1274,7 @@ class _FileManagerViewState extends State<FileManagerView> {
final x = offset.dx;
final y = offset.dy + size.height + 1;
final isPeerWindows = model.getCurrentIsWindows(isLocal);
final isPeerWindows = controller.options.value.isWindows;
final List<MenuEntryBase> menuItems = [
MenuEntryButton(
childBuilder: (TextStyle? style) => isPeerWindows
@ -1300,7 +1284,7 @@ class _FileManagerViewState extends State<FileManagerView> {
style: style,
),
proc: () {
openDirectory('/', isLocal: isLocal);
controller.openDirectory('/');
},
dismissOnClicked: true),
MenuEntryDivider()
@ -1311,8 +1295,9 @@ class _FileManagerViewState extends State<FileManagerView> {
loadingTag = _ffi.dialogManager.showLoading("Waiting");
}
try {
final fd =
await model.fetchDirectory("/", isLocal, isLocal);
final showHidden = controller.options.value.showHidden;
final fd = await controller.fileFetcher
.fetchDirectory("/", isLocal, showHidden);
for (var entry in fd.entries) {
menuItems.add(MenuEntryButton(
childBuilder: (TextStyle? style) =>
@ -1331,8 +1316,7 @@ class _FileManagerViewState extends State<FileManagerView> {
)
]),
proc: () {
openDirectory('${entry.name}\\',
isLocal: isLocal);
controller.openDirectory('${entry.name}\\');
},
dismissOnClicked: true));
}
@ -1369,9 +1353,9 @@ class _FileManagerViewState extends State<FileManagerView> {
List<BreadCrumbItem> getPathBreadCrumbItems(
bool isLocal, void Function(List<String>) onPressed) {
final path = model.getCurrentDir(isLocal).path;
final path = controller.directory.value.path;
final breadCrumbList = List<BreadCrumbItem>.empty(growable: true);
final isWindows = model.getCurrentIsWindows(isLocal);
final isWindows = controller.options.value.isWindows;
if (isWindows && path == '/') {
breadCrumbList.add(BreadCrumbItem(
content: TextButton(
@ -1403,7 +1387,7 @@ class _FileManagerViewState extends State<FileManagerView> {
return breadCrumbList;
}
breadCrumbScrollToEnd(bool isLocal) {
breadCrumbScrollToEnd() {
Future.delayed(Duration(milliseconds: 200), () {
if (_breadCrumbScroller.hasClients) {
_breadCrumbScroller.animateTo(
@ -1414,9 +1398,9 @@ class _FileManagerViewState extends State<FileManagerView> {
});
}
Widget buildPathLocation(bool isLocal) {
Widget buildPathLocation() {
final text = _locationStatus.value == LocationStatus.pathLocation
? model.getCurrentDir(isLocal).path
? controller.directory.value.path
: _searchText.value;
final textController = TextEditingController(text: text)
..selection = TextSelection.collapsed(offset: text.length);
@ -1440,7 +1424,7 @@ class _FileManagerViewState extends State<FileManagerView> {
),
controller: textController,
onSubmitted: (path) {
openDirectory(path, isLocal: isLocal);
controller.openDirectory(path);
},
onChanged: _locationStatus.value == LocationStatus.fileSearchBar
? (searchText) => onSearchText(searchText, isLocal)

View File

@ -32,35 +32,38 @@ class JobID {
}
}
class SortStyle {
var by = SortBy.name;
var ascending = true;
}
typedef GetSessionID = String Function();
class FileModel {
final WeakReference<FFI> parent;
late final String sessionID;
// late final String sessionID;
late final FileFetcher fileFetcher;
late final JobController jobController;
late final FileController localController;
late final FileController remoteController;
late final GetSessionID getSessionID;
String get sessionID => getSessionID();
FileModel(this.parent) {
sessionID = parent.target?.id ?? "";
getSessionID = () => parent.target?.id ?? "";
fileFetcher = FileFetcher(getSessionID);
jobController = JobController(getSessionID);
localController = FileController(
isLocal: true,
getSessionID: getSessionID,
dialogManager: parent.target?.dialogManager,
jobController: jobController,
fileFetcher: fileFetcher);
remoteController = FileController(
isLocal: false,
getSessionID: getSessionID,
dialogManager: parent.target?.dialogManager,
jobController: jobController,
fileFetcher: fileFetcher);
}
late final fileFetcher = FileFetcher(sessionID);
late final jobController = JobController(sessionID);
late final localController = FileController(
isLocal: true,
sessionID: sessionID,
dialogManager: parent.target?.dialogManager,
jobController: jobController,
fileFetcher: fileFetcher);
late final remoteController = FileController(
isLocal: false,
sessionID: sessionID,
dialogManager: parent.target?.dialogManager,
jobController: jobController,
fileFetcher: fileFetcher);
Future<void> onReady() async {
await localController.onReady();
await remoteController.onReady();
@ -188,7 +191,8 @@ class FileModel {
class FileController {
final bool isLocal;
final String sessionID;
final GetSessionID getSessionID;
String get sessionID => getSessionID();
final FileFetcher fileFetcher;
@ -196,13 +200,14 @@ class FileController {
final directory = FileDirectory().obs;
final history = RxList<String>.empty(growable: true);
final sortStyle = SortStyle().obs;
final sortBy = SortBy.name.obs;
final sortAscending = true.obs;
final JobController jobController;
final OverlayDialogManager? dialogManager;
FileController(
{required this.isLocal,
required this.sessionID,
required this.getSessionID,
required this.dialogManager,
required this.jobController,
required this.fileFetcher});
@ -265,8 +270,8 @@ class FileController {
}
void changeSortStyle(SortBy sort, {bool? isLocal, bool ascending = true}) {
sortStyle.value.by = sort;
sortStyle.value.ascending = ascending;
sortBy.value = sort;
sortAscending.value = ascending;
directory.value.changeSortStyle(sort, ascending: ascending);
}
@ -297,7 +302,7 @@ class FileController {
}
try {
final fd = await fileFetcher.fetchDirectory(path, isLocal, showHidden);
fd.format(isWindows, sort: sortStyle.value.by);
fd.format(isWindows, sort: sortBy.value);
directory.value = fd;
} catch (e) {
debugPrint("Failed to openDirectory $path: $e");
@ -342,7 +347,7 @@ class FileController {
void initDirAndHome(Map<String, dynamic> evt) {
try {
final fd = FileDirectory.fromJson(jsonDecode(evt['value']));
fd.format(options.value.isWindows, sort: sortStyle.value.by);
fd.format(options.value.isWindows, sort: sortBy.value);
if (fd.id > 0) {
final jobIndex = jobController.getJob(fd.id);
if (jobIndex != -1) {
@ -575,9 +580,10 @@ class JobController {
static final JobID jobID = JobID();
final jobTable = RxList<JobProgress>.empty(growable: true);
final jobResultListener = JobResultListener<Map<String, dynamic>>();
final String sessionID;
final GetSessionID getSessionID;
String get sessionID => getSessionID();
JobController(this.sessionID);
JobController(this.getSessionID);
int getJob(int id) {
return jobTable.indexWhere((element) => element.id == id);
@ -764,9 +770,10 @@ class FileFetcher {
Map<String, Completer<FileDirectory>> remoteTasks = {};
Map<int, Completer<FileDirectory>> readRecursiveTasks = {};
String id;
final GetSessionID getSessionID;
String get sessionID => getSessionID();
FileFetcher(this.id);
FileFetcher(this.getSessionID);
Future<FileDirectory> registerReadTask(bool isLocal, String path) {
// final jobs = isLocal?localJobs:remoteJobs; // maybe we will use read local dir async later
@ -829,12 +836,12 @@ class FileFetcher {
try {
if (isLocal) {
final res = await bind.sessionReadLocalDirSync(
id: id ?? "", path: path, showHidden: showHidden);
id: sessionID ?? "", path: path, showHidden: showHidden);
final fd = FileDirectory.fromJson(jsonDecode(res));
return fd;
} else {
await bind.sessionReadRemoteDir(
id: id ?? "", path: path, includeHidden: showHidden);
id: sessionID ?? "", path: path, includeHidden: showHidden);
return registerReadTask(isLocal, path);
}
} catch (e) {
@ -847,7 +854,7 @@ class FileFetcher {
// TODO test Recursive is show hidden default?
try {
await bind.sessionReadDirRecursive(
id: id,
id: sessionID,
actId: actID,
path: path,
isRemote: !isLocal,
@ -1032,7 +1039,7 @@ class SelectedItems {
int get length => _items.length;
SelectedItems(this.isLocal);
SelectedItems({required this.isLocal});
add(Entry e) {
if (e.isDrive) return;