Merge pull request #876 from Kingtous/flutter_desktop
add: file transfer dual logic with bridge
This commit is contained in:
		
						commit
						1fc8957c1c
					
				| @ -11,7 +11,6 @@ import 'package:provider/provider.dart'; | ||||
| import 'package:wakelock/wakelock.dart'; | ||||
| 
 | ||||
| import '../../common.dart'; | ||||
| import '../../mobile/widgets/dialog.dart'; | ||||
| import '../../models/model.dart'; | ||||
| 
 | ||||
| class FileManagerPage extends StatefulWidget { | ||||
| @ -25,7 +24,8 @@ class FileManagerPage extends StatefulWidget { | ||||
| class _FileManagerPageState extends State<FileManagerPage> | ||||
|     with AutomaticKeepAliveClientMixin { | ||||
|   final _selectedItems = SelectedItems(); | ||||
|   final _breadCrumbScroller = ScrollController(); | ||||
|   final _breadCrumbLocalScroller = ScrollController(); | ||||
|   final _breadCrumbRemoteScroller = ScrollController(); | ||||
| 
 | ||||
|   /// FFI with name file_transfer_id | ||||
|   FFI get _ffi => ffi('ft_${widget.id}'); | ||||
| @ -66,135 +66,11 @@ class _FileManagerPageState extends State<FileManagerPage> | ||||
|               onWillPop: () async { | ||||
|                 if (model.selectMode) { | ||||
|                   model.toggleSelectMode(); | ||||
|                 } else { | ||||
|                   goBack(); | ||||
|                 } | ||||
|                 return false; | ||||
|               }, | ||||
|               child: Scaffold( | ||||
|                 backgroundColor: MyTheme.grayBg, | ||||
|                 appBar: AppBar( | ||||
|                   leading: Row(children: [ | ||||
|                     IconButton(icon: Icon(Icons.close), onPressed: clientClose), | ||||
|                   ]), | ||||
|                   centerTitle: true, | ||||
|                   // title: ToggleSwitch( | ||||
|                   //   initialLabelIndex: model.isLocal ? 0 : 1, | ||||
|                   //   activeBgColor: [MyTheme.idColor], | ||||
|                   //   inactiveBgColor: MyTheme.grayBg, | ||||
|                   //   inactiveFgColor: Colors.black54, | ||||
|                   //   totalSwitches: 2, | ||||
|                   //   minWidth: 100, | ||||
|                   //   fontSize: 15, | ||||
|                   //   iconSize: 18, | ||||
|                   //   labels: [translate("Local"), translate("Remote")], | ||||
|                   //   icons: [Icons.phone_android_sharp, Icons.screen_share], | ||||
|                   //   onToggle: (index) { | ||||
|                   //     final current = model.isLocal ? 0 : 1; | ||||
|                   //     if (index != current) { | ||||
|                   //       model.togglePage(); | ||||
|                   //     } | ||||
|                   //   }, | ||||
|                   // ), | ||||
|                   actions: [ | ||||
|                     PopupMenuButton<String>( | ||||
|                         icon: Icon(Icons.more_vert), | ||||
|                         itemBuilder: (context) { | ||||
|                           return [ | ||||
|                             PopupMenuItem( | ||||
|                               child: Row( | ||||
|                                 children: [ | ||||
|                                   Icon(Icons.refresh, color: Colors.black), | ||||
|                                   SizedBox(width: 5), | ||||
|                                   Text(translate("Refresh File")) | ||||
|                                 ], | ||||
|                               ), | ||||
|                               value: "refresh", | ||||
|                             ), | ||||
|                             PopupMenuItem( | ||||
|                               child: Row( | ||||
|                                 children: [ | ||||
|                                   Icon(Icons.check, color: Colors.black), | ||||
|                                   SizedBox(width: 5), | ||||
|                                   Text(translate("Multi Select")) | ||||
|                                 ], | ||||
|                               ), | ||||
|                               value: "select", | ||||
|                             ), | ||||
|                             PopupMenuItem( | ||||
|                               child: Row( | ||||
|                                 children: [ | ||||
|                                   Icon(Icons.folder_outlined, | ||||
|                                       color: Colors.black), | ||||
|                                   SizedBox(width: 5), | ||||
|                                   Text(translate("Create Folder")) | ||||
|                                 ], | ||||
|                               ), | ||||
|                               value: "folder", | ||||
|                             ), | ||||
|                             PopupMenuItem( | ||||
|                               child: Row( | ||||
|                                 children: [ | ||||
|                                   Icon( | ||||
|                                       model.currentShowHidden | ||||
|                                           ? Icons.check_box_outlined | ||||
|                                           : Icons.check_box_outline_blank, | ||||
|                                       color: Colors.black), | ||||
|                                   SizedBox(width: 5), | ||||
|                                   Text(translate("Show Hidden Files")) | ||||
|                                 ], | ||||
|                               ), | ||||
|                               value: "hidden", | ||||
|                             ) | ||||
|                           ]; | ||||
|                         }, | ||||
|                         onSelected: (v) { | ||||
|                           if (v == "refresh") { | ||||
|                             model.refresh(); | ||||
|                           } else if (v == "select") { | ||||
|                             _selectedItems.clear(); | ||||
|                             model.toggleSelectMode(); | ||||
|                           } else if (v == "folder") { | ||||
|                             final name = TextEditingController(); | ||||
|                             DialogManager.show((setState, close) => | ||||
|                                 CustomAlertDialog( | ||||
|                                     title: Text(translate("Create Folder")), | ||||
|                                     content: Column( | ||||
|                                       mainAxisSize: MainAxisSize.min, | ||||
|                                       children: [ | ||||
|                                         TextFormField( | ||||
|                                           decoration: InputDecoration( | ||||
|                                             labelText: translate( | ||||
|                                                 "Please enter the folder name"), | ||||
|                                           ), | ||||
|                                           controller: name, | ||||
|                                         ), | ||||
|                                       ], | ||||
|                                     ), | ||||
|                                     actions: [ | ||||
|                                       TextButton( | ||||
|                                           style: flatButtonStyle, | ||||
|                                           onPressed: () => close(false), | ||||
|                                           child: Text(translate("Cancel"))), | ||||
|                                       ElevatedButton( | ||||
|                                           style: flatButtonStyle, | ||||
|                                           onPressed: () { | ||||
|                                             if (name.value.text.isNotEmpty) { | ||||
|                                               model.createDir(PathUtil.join( | ||||
|                                                   model.currentDir.path, | ||||
|                                                   name.value.text, | ||||
|                                                   model.currentIsWindows)); | ||||
|                                               close(); | ||||
|                                             } | ||||
|                                           }, | ||||
|                                           child: Text(translate("OK"))) | ||||
|                                     ])); | ||||
|                           } else if (v == "hidden") { | ||||
|                             model.toggleShowHidden(); | ||||
|                           } | ||||
|                         }), | ||||
|                   ], | ||||
|                 ), | ||||
|                 body: Row( | ||||
|                   children: [ | ||||
|                     Flexible(flex: 1, child: body(isLocal: true)), | ||||
| @ -213,11 +89,110 @@ class _FileManagerPageState extends State<FileManagerPage> | ||||
|     return !_selectedItems.isOtherPage(model.isLocal); | ||||
|   } | ||||
| 
 | ||||
|   Widget menu({bool isLocal = false}) { | ||||
|     return PopupMenuButton<String>( | ||||
|         icon: Icon(Icons.more_vert), | ||||
|         itemBuilder: (context) { | ||||
|           return [ | ||||
|             PopupMenuItem( | ||||
|               child: Row( | ||||
|                 children: [ | ||||
|                   Icon(Icons.refresh, color: Colors.black), | ||||
|                   SizedBox(width: 5), | ||||
|                   Text(translate("Refresh File")) | ||||
|                 ], | ||||
|               ), | ||||
|               value: "refresh", | ||||
|             ), | ||||
|             PopupMenuItem( | ||||
|               child: Row( | ||||
|                 children: [ | ||||
|                   Icon(Icons.check, color: Colors.black), | ||||
|                   SizedBox(width: 5), | ||||
|                   Text(translate("Multi Select")) | ||||
|                 ], | ||||
|               ), | ||||
|               value: "select", | ||||
|             ), | ||||
|             PopupMenuItem( | ||||
|               child: Row( | ||||
|                 children: [ | ||||
|                   Icon(Icons.folder_outlined, | ||||
|                       color: Colors.black), | ||||
|                   SizedBox(width: 5), | ||||
|                   Text(translate("Create Folder")) | ||||
|                 ], | ||||
|               ), | ||||
|               value: "folder", | ||||
|             ), | ||||
|             PopupMenuItem( | ||||
|               child: Row( | ||||
|                 children: [ | ||||
|                   Icon( | ||||
|                       model.currentShowHidden | ||||
|                           ? Icons.check_box_outlined | ||||
|                           : Icons.check_box_outline_blank, | ||||
|                       color: Colors.black), | ||||
|                   SizedBox(width: 5), | ||||
|                   Text(translate("Show Hidden Files")) | ||||
|                 ], | ||||
|               ), | ||||
|               value: "hidden", | ||||
|             ) | ||||
|           ]; | ||||
|         }, | ||||
|         onSelected: (v) { | ||||
|           if (v == "refresh") { | ||||
|             model.refresh(); | ||||
|           } else if (v == "select") { | ||||
|             _selectedItems.clear(); | ||||
|             model.toggleSelectMode(); | ||||
|           } else if (v == "folder") { | ||||
|             final name = TextEditingController(); | ||||
|             DialogManager.show((setState, close) => | ||||
|                 CustomAlertDialog( | ||||
|                     title: Text(translate("Create Folder")), | ||||
|                     content: Column( | ||||
|                       mainAxisSize: MainAxisSize.min, | ||||
|                       children: [ | ||||
|                         TextFormField( | ||||
|                           decoration: InputDecoration( | ||||
|                             labelText: translate( | ||||
|                                 "Please enter the folder name"), | ||||
|                           ), | ||||
|                           controller: name, | ||||
|                         ), | ||||
|                       ], | ||||
|                     ), | ||||
|                     actions: [ | ||||
|                       TextButton( | ||||
|                           style: flatButtonStyle, | ||||
|                           onPressed: () => close(false), | ||||
|                           child: Text(translate("Cancel"))), | ||||
|                       ElevatedButton( | ||||
|                           style: flatButtonStyle, | ||||
|                           onPressed: () { | ||||
|                             if (name.value.text.isNotEmpty) { | ||||
|                               model.createDir(PathUtil.join( | ||||
|                                   model.currentDir.path, | ||||
|                                   name.value.text, | ||||
|                                   model.currentIsWindows)); | ||||
|                               close(); | ||||
|                             } | ||||
|                           }, | ||||
|                           child: Text(translate("OK"))) | ||||
|                     ])); | ||||
|           } else if (v == "hidden") { | ||||
|             model.toggleShowHidden(local: isLocal); | ||||
|           } | ||||
|         }); | ||||
|   } | ||||
| 
 | ||||
|   Widget body({bool isLocal = false}) { | ||||
|     final fd = isLocal ? model.currentLocalDir : model.currentRemoteDir; | ||||
|     final entries = fd.entries; | ||||
|     return Column(children: [ | ||||
|       headTools(), | ||||
|       headTools(isLocal), | ||||
|       Expanded( | ||||
|           child: ListView.builder( | ||||
|         itemCount: entries.length + 1, | ||||
| @ -301,8 +276,8 @@ class _FileManagerPageState extends State<FileManagerPage> | ||||
|                   return; | ||||
|                 } | ||||
|                 if (entries[index].isDirectory) { | ||||
|                   model.openDirectory(entries[index].path); | ||||
|                   breadCrumbScrollToEnd(); | ||||
|                   model.openDirectory(entries[index].path, isLocal: isLocal); | ||||
|                   breadCrumbScrollToEnd(isLocal); | ||||
|                 } else { | ||||
|                   // Perform file-related tasks. | ||||
|                 } | ||||
| @ -322,20 +297,21 @@ class _FileManagerPageState extends State<FileManagerPage> | ||||
|     ]); | ||||
|   } | ||||
| 
 | ||||
|   goBack() { | ||||
|     model.goToParentDirectory(); | ||||
|   goBack({bool? isLocal}) { | ||||
|     model.goToParentDirectory(isLocal: isLocal); | ||||
|   } | ||||
| 
 | ||||
|   breadCrumbScrollToEnd() { | ||||
|   breadCrumbScrollToEnd(bool isLocal) { | ||||
|     final controller = isLocal ? _breadCrumbLocalScroller : _breadCrumbRemoteScroller; | ||||
|     Future.delayed(Duration(milliseconds: 200), () { | ||||
|       _breadCrumbScroller.animateTo( | ||||
|           _breadCrumbScroller.position.maxScrollExtent, | ||||
|       controller.animateTo( | ||||
|           controller.position.maxScrollExtent, | ||||
|           duration: Duration(milliseconds: 200), | ||||
|           curve: Curves.fastLinearToSlowEaseIn); | ||||
|     }); | ||||
|   } | ||||
| 
 | ||||
|   Widget headTools() => Container( | ||||
|   Widget headTools(bool isLocal) => Container( | ||||
|           child: Row( | ||||
|         children: [ | ||||
|           Expanded( | ||||
| @ -353,16 +329,18 @@ class _FileManagerPageState extends State<FileManagerPage> | ||||
|                   path = PathUtil.join(path, item, model.currentIsWindows); | ||||
|                 } | ||||
|               } | ||||
|               model.openDirectory(path); | ||||
|             }), | ||||
|               model.openDirectory(path, isLocal: isLocal); | ||||
|             }, isLocal), | ||||
|             divider: Icon(Icons.chevron_right), | ||||
|             overflow: ScrollableOverflow(controller: _breadCrumbScroller), | ||||
|             overflow: ScrollableOverflow(controller: isLocal ? _breadCrumbLocalScroller : _breadCrumbRemoteScroller), | ||||
|           )), | ||||
|           Row( | ||||
|             children: [ | ||||
|               IconButton( | ||||
|                 icon: Icon(Icons.arrow_upward), | ||||
|                 onPressed: goBack, | ||||
|                 onPressed: () { | ||||
|                   goBack(isLocal: isLocal); | ||||
|                 }, | ||||
|               ), | ||||
|               PopupMenuButton<SortBy>( | ||||
|                   icon: Icon(Icons.sort), | ||||
| @ -375,7 +353,10 @@ class _FileManagerPageState extends State<FileManagerPage> | ||||
|                             )) | ||||
|                         .toList(); | ||||
|                   }, | ||||
|                   onSelected: model.changeSortStyle), | ||||
|                   onSelected: (sort) { | ||||
|                     model.changeSortStyle(sort, isLocal: isLocal); | ||||
|                   }), | ||||
|               menu(isLocal: isLocal) | ||||
|             ], | ||||
|           ) | ||||
|         ], | ||||
| @ -486,8 +467,8 @@ class _FileManagerPageState extends State<FileManagerPage> | ||||
|   } | ||||
| 
 | ||||
|   List<BreadCrumbItem> getPathBreadCrumbItems( | ||||
|       void Function() onHome, void Function(List<String>) onPressed) { | ||||
|     final path = model.currentShortPath; | ||||
|       void Function() onHome, void Function(List<String>) onPressed, bool isLocal) { | ||||
|     final path = model.shortPath(isLocal); | ||||
|     final list = PathUtil.split(path, model.currentIsWindows); | ||||
|     final breadCrumbList = [ | ||||
|       BreadCrumbItem( | ||||
|  | ||||
| @ -5,6 +5,7 @@ import 'package:flutter/material.dart'; | ||||
| import 'package:flutter_hbb/desktop/pages/file_manager_page.dart'; | ||||
| import 'package:flutter_hbb/desktop/widgets/titlebar_widget.dart'; | ||||
| import 'package:flutter_hbb/utils/multi_window_manager.dart'; | ||||
| import 'package:get/get.dart'; | ||||
| 
 | ||||
| /// File Transfer for multi tabs | ||||
| class FileManagerTabPage extends StatefulWidget { | ||||
| @ -21,7 +22,7 @@ class _FileManagerTabPageState extends State<FileManagerTabPage> | ||||
|   // refactor List<int> when using multi-tab | ||||
|   // this singleton is only for test | ||||
|   List<String> connectionIds = List.empty(growable: true); | ||||
|   var initialIndex = 0; | ||||
|   var initialIndex = 0.obs; | ||||
| 
 | ||||
|   _FileManagerTabPageState(Map<String, dynamic> params) { | ||||
|     if (params['id'] != null) { | ||||
| @ -37,21 +38,15 @@ class _FileManagerTabPageState extends State<FileManagerTabPage> | ||||
|           "call ${call.method} with args ${call.arguments} from window ${fromWindowId}"); | ||||
|       // for simplify, just replace connectionId | ||||
|       if (call.method == "new_file_transfer") { | ||||
|         setState(() { | ||||
|           final args = jsonDecode(call.arguments); | ||||
|           final id = args['id']; | ||||
|           final indexOf = connectionIds.indexOf(id); | ||||
|           if (indexOf >= 0) { | ||||
|             setState(() { | ||||
|               initialIndex = indexOf; | ||||
|             }); | ||||
|           } else { | ||||
|             connectionIds.add(id); | ||||
|             setState(() { | ||||
|               initialIndex = connectionIds.length - 1; | ||||
|             }); | ||||
|           } | ||||
|         }); | ||||
|         final args = jsonDecode(call.arguments); | ||||
|         final id = args['id']; | ||||
|         final indexOf = connectionIds.indexOf(id); | ||||
|         if (indexOf >= 0) { | ||||
|           initialIndex.value = indexOf; | ||||
|         } else { | ||||
|           connectionIds.add(id); | ||||
|           initialIndex.value = connectionIds.length - 1; | ||||
|         } | ||||
|       } | ||||
|     }); | ||||
|   } | ||||
| @ -59,51 +54,53 @@ class _FileManagerTabPageState extends State<FileManagerTabPage> | ||||
|   @override | ||||
|   Widget build(BuildContext context) { | ||||
|     return Scaffold( | ||||
|       body: DefaultTabController( | ||||
|         initialIndex: initialIndex, | ||||
|         length: connectionIds.length, | ||||
|         animationDuration: Duration.zero, | ||||
|         child: Column( | ||||
|           children: [ | ||||
|             DesktopTitleBar( | ||||
|               child: TabBar( | ||||
|                   isScrollable: true, | ||||
|                   labelColor: Colors.white, | ||||
|                   physics: NeverScrollableScrollPhysics(), | ||||
|                   indicatorColor: Colors.white, | ||||
|                   tabs: connectionIds | ||||
|                       .map((e) => Tab( | ||||
|                             child: Row( | ||||
|                               mainAxisSize: MainAxisSize.min, | ||||
|                               crossAxisAlignment: CrossAxisAlignment.center, | ||||
|                               children: [ | ||||
|                                 Text(e), | ||||
|                                 SizedBox( | ||||
|                                   width: 4, | ||||
|                                 ), | ||||
|                                 InkWell( | ||||
|                                     onTap: () { | ||||
|                                       onRemoveId(e); | ||||
|                                     }, | ||||
|                                     child: Icon( | ||||
|                                       Icons.highlight_remove, | ||||
|                                       size: 20, | ||||
|                                     )) | ||||
|                               ], | ||||
|                             ), | ||||
|                           )) | ||||
|                       .toList()), | ||||
|             ), | ||||
|             Expanded( | ||||
|               child: TabBarView( | ||||
|                   children: connectionIds | ||||
|                       .map((e) => Container( | ||||
|                           child: FileManagerPage( | ||||
|                               key: ValueKey(e), | ||||
|                               id: e))) //RemotePage(key: ValueKey(e), id: e)) | ||||
|                       .toList()), | ||||
|             ) | ||||
|           ], | ||||
|       body: Obx( | ||||
|         ()=> DefaultTabController( | ||||
|           initialIndex: initialIndex.value, | ||||
|           length: connectionIds.length, | ||||
|           animationDuration: Duration.zero, | ||||
|           child: Column( | ||||
|             children: [ | ||||
|               DesktopTitleBar( | ||||
|                 child: TabBar( | ||||
|                     isScrollable: true, | ||||
|                     labelColor: Colors.white, | ||||
|                     physics: NeverScrollableScrollPhysics(), | ||||
|                     indicatorColor: Colors.white, | ||||
|                     tabs: connectionIds | ||||
|                         .map((e) => Tab( | ||||
|                               child: Row( | ||||
|                                 mainAxisSize: MainAxisSize.min, | ||||
|                                 crossAxisAlignment: CrossAxisAlignment.center, | ||||
|                                 children: [ | ||||
|                                   Text(e), | ||||
|                                   SizedBox( | ||||
|                                     width: 4, | ||||
|                                   ), | ||||
|                                   InkWell( | ||||
|                                       onTap: () { | ||||
|                                         onRemoveId(e); | ||||
|                                       }, | ||||
|                                       child: Icon( | ||||
|                                         Icons.highlight_remove, | ||||
|                                         size: 20, | ||||
|                                       )) | ||||
|                                 ], | ||||
|                               ), | ||||
|                             )) | ||||
|                         .toList()), | ||||
|               ), | ||||
|               Expanded( | ||||
|                 child: TabBarView( | ||||
|                     children: connectionIds | ||||
|                         .map((e) => Container( | ||||
|                             child: FileManagerPage( | ||||
|                                 key: ValueKey(e), | ||||
|                                 id: e))) //RemotePage(key: ValueKey(e), id: e)) | ||||
|                         .toList()), | ||||
|               ) | ||||
|             ], | ||||
|           ), | ||||
|         ), | ||||
|       ), | ||||
|     ); | ||||
| @ -114,9 +111,7 @@ class _FileManagerTabPageState extends State<FileManagerTabPage> | ||||
|     if (indexOf == -1) { | ||||
|       return; | ||||
|     } | ||||
|     setState(() { | ||||
|       connectionIds.removeAt(indexOf); | ||||
|       initialIndex = max(0, initialIndex - 1); | ||||
|     }); | ||||
|     connectionIds.removeAt(indexOf); | ||||
|     initialIndex.value = max(0, initialIndex.value - 1); | ||||
|   } | ||||
| } | ||||
|  | ||||
| @ -60,6 +60,21 @@ class FileModel extends ChangeNotifier { | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   String shortPath(bool isLocal) { | ||||
|     final dir = isLocal ? currentLocalDir : currentRemoteDir; | ||||
|     if (dir.path.startsWith(currentHome)) { | ||||
|       var path = dir.path.replaceFirst(currentHome, ""); | ||||
|       if (path.length == 0) return ""; | ||||
|       if (path[0] == "/" || path[0] == "\\") { | ||||
|         // remove more '/' or '\' | ||||
|         path = path.replaceFirst(path[0], ""); | ||||
|       } | ||||
|       return path; | ||||
|     } else { | ||||
|       return dir.path.replaceFirst(currentHome, ""); | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   bool get currentShowHidden => | ||||
|       _isLocal ? _localOption.showHidden : _remoteOption.showHidden; | ||||
| 
 | ||||
| @ -265,9 +280,9 @@ class FileModel extends ChangeNotifier { | ||||
|     openDirectory(currentHome); | ||||
|   } | ||||
| 
 | ||||
|   goToParentDirectory() { | ||||
|   goToParentDirectory({bool? isLocal}) { | ||||
|     final parent = PathUtil.dirname(currentDir.path, currentIsWindows); | ||||
|     openDirectory(parent); | ||||
|     openDirectory(parent, isLocal: isLocal); | ||||
|   } | ||||
| 
 | ||||
|   sendFiles(SelectedItems items) { | ||||
| @ -282,17 +297,10 @@ class FileModel extends ChangeNotifier { | ||||
|         items.isLocal! ? _localOption.isWindows : _remoteOption.isWindows; | ||||
|     final showHidden = | ||||
|         items.isLocal! ? _localOption.showHidden : _remoteOption.showHidden; | ||||
|     items.items.forEach((from) { | ||||
|     items.items.forEach((from) async { | ||||
|       _jobId++; | ||||
|       final msg = { | ||||
|         "id": _jobId.toString(), | ||||
|         "path": from.path, | ||||
|         "to": PathUtil.join(toPath, from.name, isWindows), | ||||
|         "file_num": "0", | ||||
|         "show_hidden": showHidden.toString(), | ||||
|         "is_remote": (!(items.isLocal!)).toString() | ||||
|       }; | ||||
|       _ffi.target?.setByName("send_files", jsonEncode(msg)); | ||||
|       await _ffi.target?.bind.sessionSendFiles(id: '${_ffi.target?.getId()}', actId: _jobId, path: from.path, to: PathUtil.join(toPath, from.name, isWindows) | ||||
|           ,fileNum: 0, includeHidden: showHidden, isRemote: !(items.isLocal!)); | ||||
|     }); | ||||
|   } | ||||
| 
 | ||||
| @ -485,43 +493,34 @@ class FileModel extends ChangeNotifier { | ||||
|   } | ||||
| 
 | ||||
|   sendRemoveFile(String path, int fileNum, bool isLocal) { | ||||
|     final msg = { | ||||
|       "id": _jobId.toString(), | ||||
|       "path": path, | ||||
|       "file_num": fileNum.toString(), | ||||
|       "is_remote": (!(isLocal)).toString() | ||||
|     }; | ||||
|     _ffi.target?.setByName("remove_file", jsonEncode(msg)); | ||||
|     _ffi.target?.bind.sessionRemoveFile(id: '${_ffi.target?.getId()}', actId: _jobId, path: path, isRemote: !isLocal, fileNum: fileNum); | ||||
|   } | ||||
| 
 | ||||
|   sendRemoveEmptyDir(String path, int fileNum, bool isLocal) { | ||||
|     final msg = { | ||||
|       "id": _jobId.toString(), | ||||
|       "path": path, | ||||
|       "is_remote": (!isLocal).toString() | ||||
|     }; | ||||
|     _ffi.target?.setByName("remove_all_empty_dirs", jsonEncode(msg)); | ||||
|     _ffi.target?.bind.sessionRemoveAllEmptyDirs(id: '${_ffi.target?.getId()}', actId: _jobId, path: path, isRemote: !isLocal); | ||||
|   } | ||||
| 
 | ||||
|   createDir(String path) { | ||||
|   createDir(String path) async { | ||||
|     _jobId++; | ||||
|     final msg = { | ||||
|       "id": _jobId.toString(), | ||||
|       "path": path, | ||||
|       "is_remote": (!isLocal).toString() | ||||
|     }; | ||||
|     _ffi.target?.setByName("create_dir", jsonEncode(msg)); | ||||
|     _ffi.target?.bind.sessionCreateDir(id: '${_ffi.target?.getId()}', actId: _jobId, path: path, isRemote: !isLocal); | ||||
|   } | ||||
| 
 | ||||
|   cancelJob(int id) { | ||||
|     _ffi.target?.setByName("cancel_job", id.toString()); | ||||
|   cancelJob(int id) async { | ||||
|     _ffi.target?.bind.sessionCancelJob(id: '${_ffi.target?.getId()}', actId: id); | ||||
|     jobReset(); | ||||
|   } | ||||
| 
 | ||||
|   changeSortStyle(SortBy sort) { | ||||
|   changeSortStyle(SortBy sort, {bool? isLocal}) { | ||||
|     _sortStyle = sort; | ||||
|     _currentLocalDir.changeSortStyle(sort); | ||||
|     _currentRemoteDir.changeSortStyle(sort); | ||||
|     if (isLocal == null) { | ||||
|       // compatible for mobile logic | ||||
|       _currentLocalDir.changeSortStyle(sort); | ||||
|       _currentRemoteDir.changeSortStyle(sort); | ||||
|     } else if (isLocal) { | ||||
|       _currentLocalDir.changeSortStyle(sort); | ||||
|     } else { | ||||
|       _currentRemoteDir.changeSortStyle(sort); | ||||
|     } | ||||
|     notifyListeners(); | ||||
|   } | ||||
| 
 | ||||
|  | ||||
| @ -101,7 +101,7 @@ class RustDeskMultiWindowManager { | ||||
|       case WindowType.RemoteDesktop: | ||||
|         return _remoteDesktopWindowId; | ||||
|       case WindowType.FileTransfer: | ||||
|         break; | ||||
|         return _fileTransferWindowId; | ||||
|       case WindowType.PortForward: | ||||
|         break; | ||||
|       case WindowType.Unknown: | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user