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 'package:wakelock/wakelock.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import '../../common.dart';
 | 
					import '../../common.dart';
 | 
				
			||||||
import '../../mobile/widgets/dialog.dart';
 | 
					 | 
				
			||||||
import '../../models/model.dart';
 | 
					import '../../models/model.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class FileManagerPage extends StatefulWidget {
 | 
					class FileManagerPage extends StatefulWidget {
 | 
				
			||||||
@ -25,7 +24,8 @@ class FileManagerPage extends StatefulWidget {
 | 
				
			|||||||
class _FileManagerPageState extends State<FileManagerPage>
 | 
					class _FileManagerPageState extends State<FileManagerPage>
 | 
				
			||||||
    with AutomaticKeepAliveClientMixin {
 | 
					    with AutomaticKeepAliveClientMixin {
 | 
				
			||||||
  final _selectedItems = SelectedItems();
 | 
					  final _selectedItems = SelectedItems();
 | 
				
			||||||
  final _breadCrumbScroller = ScrollController();
 | 
					  final _breadCrumbLocalScroller = ScrollController();
 | 
				
			||||||
 | 
					  final _breadCrumbRemoteScroller = ScrollController();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /// FFI with name file_transfer_id
 | 
					  /// FFI with name file_transfer_id
 | 
				
			||||||
  FFI get _ffi => ffi('ft_${widget.id}');
 | 
					  FFI get _ffi => ffi('ft_${widget.id}');
 | 
				
			||||||
@ -66,38 +66,31 @@ class _FileManagerPageState extends State<FileManagerPage>
 | 
				
			|||||||
              onWillPop: () async {
 | 
					              onWillPop: () async {
 | 
				
			||||||
                if (model.selectMode) {
 | 
					                if (model.selectMode) {
 | 
				
			||||||
                  model.toggleSelectMode();
 | 
					                  model.toggleSelectMode();
 | 
				
			||||||
                } else {
 | 
					 | 
				
			||||||
                  goBack();
 | 
					 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                return false;
 | 
					                return false;
 | 
				
			||||||
              },
 | 
					              },
 | 
				
			||||||
              child: Scaffold(
 | 
					              child: Scaffold(
 | 
				
			||||||
                backgroundColor: MyTheme.grayBg,
 | 
					                backgroundColor: MyTheme.grayBg,
 | 
				
			||||||
                appBar: AppBar(
 | 
					                body: Row(
 | 
				
			||||||
                  leading: Row(children: [
 | 
					                  children: [
 | 
				
			||||||
                    IconButton(icon: Icon(Icons.close), onPressed: clientClose),
 | 
					                    Flexible(flex: 1, child: body(isLocal: true)),
 | 
				
			||||||
                  ]),
 | 
					                    Flexible(flex: 1, child: body(isLocal: false))
 | 
				
			||||||
                  centerTitle: true,
 | 
					                  ],
 | 
				
			||||||
                  // title: ToggleSwitch(
 | 
					                ),
 | 
				
			||||||
                  //   initialLabelIndex: model.isLocal ? 0 : 1,
 | 
					                bottomSheet: bottomSheet(),
 | 
				
			||||||
                  //   activeBgColor: [MyTheme.idColor],
 | 
					              ));
 | 
				
			||||||
                  //   inactiveBgColor: MyTheme.grayBg,
 | 
					        }));
 | 
				
			||||||
                  //   inactiveFgColor: Colors.black54,
 | 
					  }
 | 
				
			||||||
                  //   totalSwitches: 2,
 | 
					
 | 
				
			||||||
                  //   minWidth: 100,
 | 
					  bool needShowCheckBox() {
 | 
				
			||||||
                  //   fontSize: 15,
 | 
					    if (!model.selectMode) {
 | 
				
			||||||
                  //   iconSize: 18,
 | 
					      return false;
 | 
				
			||||||
                  //   labels: [translate("Local"), translate("Remote")],
 | 
					    }
 | 
				
			||||||
                  //   icons: [Icons.phone_android_sharp, Icons.screen_share],
 | 
					    return !_selectedItems.isOtherPage(model.isLocal);
 | 
				
			||||||
                  //   onToggle: (index) {
 | 
					  }
 | 
				
			||||||
                  //     final current = model.isLocal ? 0 : 1;
 | 
					
 | 
				
			||||||
                  //     if (index != current) {
 | 
					  Widget menu({bool isLocal = false}) {
 | 
				
			||||||
                  //       model.togglePage();
 | 
					    return PopupMenuButton<String>(
 | 
				
			||||||
                  //     }
 | 
					 | 
				
			||||||
                  //   },
 | 
					 | 
				
			||||||
                  // ),
 | 
					 | 
				
			||||||
                  actions: [
 | 
					 | 
				
			||||||
                    PopupMenuButton<String>(
 | 
					 | 
				
			||||||
        icon: Icon(Icons.more_vert),
 | 
					        icon: Icon(Icons.more_vert),
 | 
				
			||||||
        itemBuilder: (context) {
 | 
					        itemBuilder: (context) {
 | 
				
			||||||
          return [
 | 
					          return [
 | 
				
			||||||
@ -190,34 +183,16 @@ class _FileManagerPageState extends State<FileManagerPage>
 | 
				
			|||||||
                          child: Text(translate("OK")))
 | 
					                          child: Text(translate("OK")))
 | 
				
			||||||
                    ]));
 | 
					                    ]));
 | 
				
			||||||
          } else if (v == "hidden") {
 | 
					          } else if (v == "hidden") {
 | 
				
			||||||
                            model.toggleShowHidden();
 | 
					            model.toggleShowHidden(local: isLocal);
 | 
				
			||||||
          }
 | 
					          }
 | 
				
			||||||
                        }),
 | 
					        });
 | 
				
			||||||
                  ],
 | 
					 | 
				
			||||||
                ),
 | 
					 | 
				
			||||||
                body: Row(
 | 
					 | 
				
			||||||
                  children: [
 | 
					 | 
				
			||||||
                    Flexible(flex: 1, child: body(isLocal: true)),
 | 
					 | 
				
			||||||
                    Flexible(flex: 1, child: body(isLocal: false))
 | 
					 | 
				
			||||||
                  ],
 | 
					 | 
				
			||||||
                ),
 | 
					 | 
				
			||||||
                bottomSheet: bottomSheet(),
 | 
					 | 
				
			||||||
              ));
 | 
					 | 
				
			||||||
        }));
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  bool needShowCheckBox() {
 | 
					 | 
				
			||||||
    if (!model.selectMode) {
 | 
					 | 
				
			||||||
      return false;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    return !_selectedItems.isOtherPage(model.isLocal);
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  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 Column(children: [
 | 
				
			||||||
      headTools(),
 | 
					      headTools(isLocal),
 | 
				
			||||||
      Expanded(
 | 
					      Expanded(
 | 
				
			||||||
          child: ListView.builder(
 | 
					          child: ListView.builder(
 | 
				
			||||||
        itemCount: entries.length + 1,
 | 
					        itemCount: entries.length + 1,
 | 
				
			||||||
@ -301,8 +276,8 @@ class _FileManagerPageState extends State<FileManagerPage>
 | 
				
			|||||||
                  return;
 | 
					                  return;
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                if (entries[index].isDirectory) {
 | 
					                if (entries[index].isDirectory) {
 | 
				
			||||||
                  model.openDirectory(entries[index].path);
 | 
					                  model.openDirectory(entries[index].path, isLocal: isLocal);
 | 
				
			||||||
                  breadCrumbScrollToEnd();
 | 
					                  breadCrumbScrollToEnd(isLocal);
 | 
				
			||||||
                } else {
 | 
					                } else {
 | 
				
			||||||
                  // Perform file-related tasks.
 | 
					                  // Perform file-related tasks.
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
@ -322,20 +297,21 @@ class _FileManagerPageState extends State<FileManagerPage>
 | 
				
			|||||||
    ]);
 | 
					    ]);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  goBack() {
 | 
					  goBack({bool? isLocal}) {
 | 
				
			||||||
    model.goToParentDirectory();
 | 
					    model.goToParentDirectory(isLocal: isLocal);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  breadCrumbScrollToEnd() {
 | 
					  breadCrumbScrollToEnd(bool isLocal) {
 | 
				
			||||||
 | 
					    final controller = isLocal ? _breadCrumbLocalScroller : _breadCrumbRemoteScroller;
 | 
				
			||||||
    Future.delayed(Duration(milliseconds: 200), () {
 | 
					    Future.delayed(Duration(milliseconds: 200), () {
 | 
				
			||||||
      _breadCrumbScroller.animateTo(
 | 
					      controller.animateTo(
 | 
				
			||||||
          _breadCrumbScroller.position.maxScrollExtent,
 | 
					          controller.position.maxScrollExtent,
 | 
				
			||||||
          duration: Duration(milliseconds: 200),
 | 
					          duration: Duration(milliseconds: 200),
 | 
				
			||||||
          curve: Curves.fastLinearToSlowEaseIn);
 | 
					          curve: Curves.fastLinearToSlowEaseIn);
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  Widget headTools() => Container(
 | 
					  Widget headTools(bool isLocal) => Container(
 | 
				
			||||||
          child: Row(
 | 
					          child: Row(
 | 
				
			||||||
        children: [
 | 
					        children: [
 | 
				
			||||||
          Expanded(
 | 
					          Expanded(
 | 
				
			||||||
@ -353,16 +329,18 @@ class _FileManagerPageState extends State<FileManagerPage>
 | 
				
			|||||||
                  path = PathUtil.join(path, item, model.currentIsWindows);
 | 
					                  path = PathUtil.join(path, item, model.currentIsWindows);
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
              }
 | 
					              }
 | 
				
			||||||
              model.openDirectory(path);
 | 
					              model.openDirectory(path, isLocal: isLocal);
 | 
				
			||||||
            }),
 | 
					            }, isLocal),
 | 
				
			||||||
            divider: Icon(Icons.chevron_right),
 | 
					            divider: Icon(Icons.chevron_right),
 | 
				
			||||||
            overflow: ScrollableOverflow(controller: _breadCrumbScroller),
 | 
					            overflow: ScrollableOverflow(controller: isLocal ? _breadCrumbLocalScroller : _breadCrumbRemoteScroller),
 | 
				
			||||||
          )),
 | 
					          )),
 | 
				
			||||||
          Row(
 | 
					          Row(
 | 
				
			||||||
            children: [
 | 
					            children: [
 | 
				
			||||||
              IconButton(
 | 
					              IconButton(
 | 
				
			||||||
                icon: Icon(Icons.arrow_upward),
 | 
					                icon: Icon(Icons.arrow_upward),
 | 
				
			||||||
                onPressed: goBack,
 | 
					                onPressed: () {
 | 
				
			||||||
 | 
					                  goBack(isLocal: isLocal);
 | 
				
			||||||
 | 
					                },
 | 
				
			||||||
              ),
 | 
					              ),
 | 
				
			||||||
              PopupMenuButton<SortBy>(
 | 
					              PopupMenuButton<SortBy>(
 | 
				
			||||||
                  icon: Icon(Icons.sort),
 | 
					                  icon: Icon(Icons.sort),
 | 
				
			||||||
@ -375,7 +353,10 @@ class _FileManagerPageState extends State<FileManagerPage>
 | 
				
			|||||||
                            ))
 | 
					                            ))
 | 
				
			||||||
                        .toList();
 | 
					                        .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(
 | 
					  List<BreadCrumbItem> getPathBreadCrumbItems(
 | 
				
			||||||
      void Function() onHome, void Function(List<String>) onPressed) {
 | 
					      void Function() onHome, void Function(List<String>) onPressed, bool isLocal) {
 | 
				
			||||||
    final path = model.currentShortPath;
 | 
					    final path = model.shortPath(isLocal);
 | 
				
			||||||
    final list = PathUtil.split(path, model.currentIsWindows);
 | 
					    final list = PathUtil.split(path, model.currentIsWindows);
 | 
				
			||||||
    final breadCrumbList = [
 | 
					    final breadCrumbList = [
 | 
				
			||||||
      BreadCrumbItem(
 | 
					      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/pages/file_manager_page.dart';
 | 
				
			||||||
import 'package:flutter_hbb/desktop/widgets/titlebar_widget.dart';
 | 
					import 'package:flutter_hbb/desktop/widgets/titlebar_widget.dart';
 | 
				
			||||||
import 'package:flutter_hbb/utils/multi_window_manager.dart';
 | 
					import 'package:flutter_hbb/utils/multi_window_manager.dart';
 | 
				
			||||||
 | 
					import 'package:get/get.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// File Transfer for multi tabs
 | 
					/// File Transfer for multi tabs
 | 
				
			||||||
class FileManagerTabPage extends StatefulWidget {
 | 
					class FileManagerTabPage extends StatefulWidget {
 | 
				
			||||||
@ -21,7 +22,7 @@ class _FileManagerTabPageState extends State<FileManagerTabPage>
 | 
				
			|||||||
  // refactor List<int> when using multi-tab
 | 
					  // refactor List<int> when using multi-tab
 | 
				
			||||||
  // this singleton is only for test
 | 
					  // this singleton is only for test
 | 
				
			||||||
  List<String> connectionIds = List.empty(growable: true);
 | 
					  List<String> connectionIds = List.empty(growable: true);
 | 
				
			||||||
  var initialIndex = 0;
 | 
					  var initialIndex = 0.obs;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  _FileManagerTabPageState(Map<String, dynamic> params) {
 | 
					  _FileManagerTabPageState(Map<String, dynamic> params) {
 | 
				
			||||||
    if (params['id'] != null) {
 | 
					    if (params['id'] != null) {
 | 
				
			||||||
@ -37,21 +38,15 @@ class _FileManagerTabPageState extends State<FileManagerTabPage>
 | 
				
			|||||||
          "call ${call.method} with args ${call.arguments} from window ${fromWindowId}");
 | 
					          "call ${call.method} with args ${call.arguments} from window ${fromWindowId}");
 | 
				
			||||||
      // for simplify, just replace connectionId
 | 
					      // for simplify, just replace connectionId
 | 
				
			||||||
      if (call.method == "new_file_transfer") {
 | 
					      if (call.method == "new_file_transfer") {
 | 
				
			||||||
        setState(() {
 | 
					 | 
				
			||||||
        final args = jsonDecode(call.arguments);
 | 
					        final args = jsonDecode(call.arguments);
 | 
				
			||||||
        final id = args['id'];
 | 
					        final id = args['id'];
 | 
				
			||||||
        final indexOf = connectionIds.indexOf(id);
 | 
					        final indexOf = connectionIds.indexOf(id);
 | 
				
			||||||
        if (indexOf >= 0) {
 | 
					        if (indexOf >= 0) {
 | 
				
			||||||
            setState(() {
 | 
					          initialIndex.value = indexOf;
 | 
				
			||||||
              initialIndex = indexOf;
 | 
					 | 
				
			||||||
            });
 | 
					 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
          connectionIds.add(id);
 | 
					          connectionIds.add(id);
 | 
				
			||||||
            setState(() {
 | 
					          initialIndex.value = connectionIds.length - 1;
 | 
				
			||||||
              initialIndex = connectionIds.length - 1;
 | 
					 | 
				
			||||||
            });
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
@ -59,8 +54,9 @@ class _FileManagerTabPageState extends State<FileManagerTabPage>
 | 
				
			|||||||
  @override
 | 
					  @override
 | 
				
			||||||
  Widget build(BuildContext context) {
 | 
					  Widget build(BuildContext context) {
 | 
				
			||||||
    return Scaffold(
 | 
					    return Scaffold(
 | 
				
			||||||
      body: DefaultTabController(
 | 
					      body: Obx(
 | 
				
			||||||
        initialIndex: initialIndex,
 | 
					        ()=> DefaultTabController(
 | 
				
			||||||
 | 
					          initialIndex: initialIndex.value,
 | 
				
			||||||
          length: connectionIds.length,
 | 
					          length: connectionIds.length,
 | 
				
			||||||
          animationDuration: Duration.zero,
 | 
					          animationDuration: Duration.zero,
 | 
				
			||||||
          child: Column(
 | 
					          child: Column(
 | 
				
			||||||
@ -106,6 +102,7 @@ class _FileManagerTabPageState extends State<FileManagerTabPage>
 | 
				
			|||||||
            ],
 | 
					            ],
 | 
				
			||||||
          ),
 | 
					          ),
 | 
				
			||||||
        ),
 | 
					        ),
 | 
				
			||||||
 | 
					      ),
 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -114,9 +111,7 @@ class _FileManagerTabPageState extends State<FileManagerTabPage>
 | 
				
			|||||||
    if (indexOf == -1) {
 | 
					    if (indexOf == -1) {
 | 
				
			||||||
      return;
 | 
					      return;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    setState(() {
 | 
					 | 
				
			||||||
    connectionIds.removeAt(indexOf);
 | 
					    connectionIds.removeAt(indexOf);
 | 
				
			||||||
      initialIndex = max(0, initialIndex - 1);
 | 
					    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 =>
 | 
					  bool get currentShowHidden =>
 | 
				
			||||||
      _isLocal ? _localOption.showHidden : _remoteOption.showHidden;
 | 
					      _isLocal ? _localOption.showHidden : _remoteOption.showHidden;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -265,9 +280,9 @@ class FileModel extends ChangeNotifier {
 | 
				
			|||||||
    openDirectory(currentHome);
 | 
					    openDirectory(currentHome);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  goToParentDirectory() {
 | 
					  goToParentDirectory({bool? isLocal}) {
 | 
				
			||||||
    final parent = PathUtil.dirname(currentDir.path, currentIsWindows);
 | 
					    final parent = PathUtil.dirname(currentDir.path, currentIsWindows);
 | 
				
			||||||
    openDirectory(parent);
 | 
					    openDirectory(parent, isLocal: isLocal);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  sendFiles(SelectedItems items) {
 | 
					  sendFiles(SelectedItems items) {
 | 
				
			||||||
@ -282,17 +297,10 @@ class FileModel extends ChangeNotifier {
 | 
				
			|||||||
        items.isLocal! ? _localOption.isWindows : _remoteOption.isWindows;
 | 
					        items.isLocal! ? _localOption.isWindows : _remoteOption.isWindows;
 | 
				
			||||||
    final showHidden =
 | 
					    final showHidden =
 | 
				
			||||||
        items.isLocal! ? _localOption.showHidden : _remoteOption.showHidden;
 | 
					        items.isLocal! ? _localOption.showHidden : _remoteOption.showHidden;
 | 
				
			||||||
    items.items.forEach((from) {
 | 
					    items.items.forEach((from) async {
 | 
				
			||||||
      _jobId++;
 | 
					      _jobId++;
 | 
				
			||||||
      final msg = {
 | 
					      await _ffi.target?.bind.sessionSendFiles(id: '${_ffi.target?.getId()}', actId: _jobId, path: from.path, to: PathUtil.join(toPath, from.name, isWindows)
 | 
				
			||||||
        "id": _jobId.toString(),
 | 
					          ,fileNum: 0, includeHidden: showHidden, isRemote: !(items.isLocal!));
 | 
				
			||||||
        "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));
 | 
					 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -485,43 +493,34 @@ class FileModel extends ChangeNotifier {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  sendRemoveFile(String path, int fileNum, bool isLocal) {
 | 
					  sendRemoveFile(String path, int fileNum, bool isLocal) {
 | 
				
			||||||
    final msg = {
 | 
					    _ffi.target?.bind.sessionRemoveFile(id: '${_ffi.target?.getId()}', actId: _jobId, path: path, isRemote: !isLocal, fileNum: fileNum);
 | 
				
			||||||
      "id": _jobId.toString(),
 | 
					 | 
				
			||||||
      "path": path,
 | 
					 | 
				
			||||||
      "file_num": fileNum.toString(),
 | 
					 | 
				
			||||||
      "is_remote": (!(isLocal)).toString()
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
    _ffi.target?.setByName("remove_file", jsonEncode(msg));
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  sendRemoveEmptyDir(String path, int fileNum, bool isLocal) {
 | 
					  sendRemoveEmptyDir(String path, int fileNum, bool isLocal) {
 | 
				
			||||||
    final msg = {
 | 
					    _ffi.target?.bind.sessionRemoveAllEmptyDirs(id: '${_ffi.target?.getId()}', actId: _jobId, path: path, isRemote: !isLocal);
 | 
				
			||||||
      "id": _jobId.toString(),
 | 
					 | 
				
			||||||
      "path": path,
 | 
					 | 
				
			||||||
      "is_remote": (!isLocal).toString()
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
    _ffi.target?.setByName("remove_all_empty_dirs", jsonEncode(msg));
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  createDir(String path) {
 | 
					  createDir(String path) async {
 | 
				
			||||||
    _jobId++;
 | 
					    _jobId++;
 | 
				
			||||||
    final msg = {
 | 
					    _ffi.target?.bind.sessionCreateDir(id: '${_ffi.target?.getId()}', actId: _jobId, path: path, isRemote: !isLocal);
 | 
				
			||||||
      "id": _jobId.toString(),
 | 
					 | 
				
			||||||
      "path": path,
 | 
					 | 
				
			||||||
      "is_remote": (!isLocal).toString()
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
    _ffi.target?.setByName("create_dir", jsonEncode(msg));
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  cancelJob(int id) {
 | 
					  cancelJob(int id) async {
 | 
				
			||||||
    _ffi.target?.setByName("cancel_job", id.toString());
 | 
					    _ffi.target?.bind.sessionCancelJob(id: '${_ffi.target?.getId()}', actId: id);
 | 
				
			||||||
    jobReset();
 | 
					    jobReset();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  changeSortStyle(SortBy sort) {
 | 
					  changeSortStyle(SortBy sort, {bool? isLocal}) {
 | 
				
			||||||
    _sortStyle = sort;
 | 
					    _sortStyle = sort;
 | 
				
			||||||
 | 
					    if (isLocal == null) {
 | 
				
			||||||
 | 
					      // compatible for mobile logic
 | 
				
			||||||
      _currentLocalDir.changeSortStyle(sort);
 | 
					      _currentLocalDir.changeSortStyle(sort);
 | 
				
			||||||
      _currentRemoteDir.changeSortStyle(sort);
 | 
					      _currentRemoteDir.changeSortStyle(sort);
 | 
				
			||||||
 | 
					    } else if (isLocal) {
 | 
				
			||||||
 | 
					      _currentLocalDir.changeSortStyle(sort);
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					      _currentRemoteDir.changeSortStyle(sort);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
    notifyListeners();
 | 
					    notifyListeners();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -101,7 +101,7 @@ class RustDeskMultiWindowManager {
 | 
				
			|||||||
      case WindowType.RemoteDesktop:
 | 
					      case WindowType.RemoteDesktop:
 | 
				
			||||||
        return _remoteDesktopWindowId;
 | 
					        return _remoteDesktopWindowId;
 | 
				
			||||||
      case WindowType.FileTransfer:
 | 
					      case WindowType.FileTransfer:
 | 
				
			||||||
        break;
 | 
					        return _fileTransferWindowId;
 | 
				
			||||||
      case WindowType.PortForward:
 | 
					      case WindowType.PortForward:
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
      case WindowType.Unknown:
 | 
					      case WindowType.Unknown:
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user