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

View File

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