Merge branch 'service'

This commit is contained in:
rustdesk 2022-04-07 21:22:40 +08:00
commit 81a2a58c2f
4 changed files with 185 additions and 138 deletions

View File

@ -76,6 +76,7 @@ class MainActivity : FlutterActivity() {
"request_permission" -> { "request_permission" -> {
if(call.arguments is String){ if(call.arguments is String){
requestPermission(context, call.arguments as String) requestPermission(context, call.arguments as String)
result.success(true)
} else { } else {
result.success(false) result.success(false)
} }

View File

@ -3,7 +3,6 @@ import 'dart:convert';
import 'package:flutter_easyloading/flutter_easyloading.dart'; import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:flutter_hbb/common.dart'; import 'package:flutter_hbb/common.dart';
import 'package:flutter_hbb/pages/file_manager_page.dart'; import 'package:flutter_hbb/pages/file_manager_page.dart';
import 'package:path/path.dart' as p;
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:path/path.dart' as Path; import 'package:path/path.dart' as Path;
@ -11,14 +10,6 @@ import 'model.dart';
enum SortBy { Name, Type, Modified, Size } enum SortBy { Name, Type, Modified, Size }
// enum FileType {
// Dir = 0,
// DirLink = 2,
// DirDrive = 3,
// File = 4,
// FileLink = 5,
// }
class FileModel extends ChangeNotifier { class FileModel extends ChangeNotifier {
var _isLocal = false; var _isLocal = false;
var _selectMode = false; var _selectMode = false;
@ -55,15 +46,15 @@ class FileModel extends ChangeNotifier {
String get currentHome => _isLocal ? _localOption.home : _remoteOption.home; String get currentHome => _isLocal ? _localOption.home : _remoteOption.home;
String get currentShortPath { String get currentShortPath {
if(currentDir.path.startsWith(currentHome)){ if (currentDir.path.startsWith(currentHome)) {
var path = currentDir.path.replaceFirst(currentHome, ""); var path = currentDir.path.replaceFirst(currentHome, "");
if(path.length ==0 ) return ""; if (path.length == 0) return "";
if(path[0] == "/" || path[0] == "\\") { if (path[0] == "/" || path[0] == "\\") {
// remove more '/' or '\' // remove more '/' or '\'
path = path.replaceFirst(path[0], ""); path = path.replaceFirst(path[0], "");
} }
return path; return path;
}else{ } else {
return currentDir.path.replaceFirst(currentHome, ""); return currentDir.path.replaceFirst(currentHome, "");
} }
} }
@ -112,6 +103,18 @@ class FileModel extends ChangeNotifier {
} }
receiveFileDir(Map<String, dynamic> evt) { receiveFileDir(Map<String, dynamic> evt) {
if (_remoteOption.home.isEmpty && evt['is_local'] == "false") {
// init remote home, the connection will automatic read remote home when established,
try {
final fd = FileDirectory.fromJson(jsonDecode(evt['value']));
fd.format(_remoteOption.isWindows, sort: _sortStyle);
_remoteOption.home = fd.path;
debugPrint("init remote home:${fd.path}");
_currentRemoteDir = fd;
notifyListeners();
return;
} finally {}
}
_fileFetcher.tryCompleteTask(evt['value'], evt['is_local']); _fileFetcher.tryCompleteTask(evt['value'], evt['is_local']);
} }
@ -143,29 +146,30 @@ class FileModel extends ChangeNotifier {
notifyListeners(); notifyListeners();
} }
onReady() { onReady() async {
_localOption = DirectoryOption( _localOption.home = FFI.getByName("get_home_dir");
home: FFI.getByName("get_home_dir"), _localOption.showHidden =
showHidden: FFI.getByName("peer_option", "local_show_hidden") != ""); FFI.getByName("peer_option", "local_show_hidden").isNotEmpty;
_remoteOption = DirectoryOption(
home: FFI.ffiModel.pi.homeDir, _remoteOption.showHidden =
showHidden: FFI.getByName("peer_option", "remote_show_hidden") != "", FFI.getByName("peer_option", "remote_show_hidden").isNotEmpty;
isWindows: FFI.ffiModel.pi.platform == "Windows"); _remoteOption.isWindows = FFI.ffiModel.pi.platform == "Windows";
debugPrint("remote platform: ${FFI.ffiModel.pi.platform}"); debugPrint("remote platform: ${FFI.ffiModel.pi.platform}");
await Future.delayed(Duration(milliseconds: 100));
final local = FFI.getByName("peer_option", "local_dir"); final local = FFI.getByName("peer_option", "local_dir");
final remote = FFI.getByName("peer_option", "remote_dir"); final remote = FFI.getByName("peer_option", "remote_dir");
openDirectory(local.isEmpty ? _localOption.home : local, isLocal: true); openDirectory(local.isEmpty ? _localOption.home : local, isLocal: true);
openDirectory(remote.isEmpty ? _remoteOption.home : remote, isLocal: false); openDirectory(remote.isEmpty ? _remoteOption.home : remote, isLocal: false);
Timer(Duration(seconds: 2), () { await Future.delayed(Duration(seconds: 1));
if (_currentLocalDir.path.isEmpty) { if (_currentLocalDir.path.isEmpty) {
openDirectory(_localOption.home, isLocal: true); openDirectory(_localOption.home, isLocal: true);
} }
if (_currentRemoteDir.path.isEmpty) { if (_currentRemoteDir.path.isEmpty) {
openDirectory(_remoteOption.home, isLocal: false); openDirectory(_remoteOption.home, isLocal: false);
} }
});
} }
onClose() { onClose() {
@ -192,6 +196,8 @@ class FileModel extends ChangeNotifier {
FFI.setByName('peer_option', jsonEncode(msg)); FFI.setByName('peer_option', jsonEncode(msg));
_currentLocalDir.clear(); _currentLocalDir.clear();
_currentRemoteDir.clear(); _currentRemoteDir.clear();
_localOption.clear();
_remoteOption.clear();
} }
refresh() { refresh() {
@ -223,7 +229,8 @@ class FileModel extends ChangeNotifier {
} }
goToParentDirectory() { goToParentDirectory() {
openDirectory(currentDir.parent); final parent = PathUtil.dirname(currentDir.path, currentIsWindows);
openDirectory(parent);
} }
sendFiles(SelectedItems items) { sendFiles(SelectedItems items) {
@ -278,7 +285,11 @@ class FileModel extends ChangeNotifier {
fd.format(isWindows); fd.format(isWindows);
EasyLoading.dismiss(); EasyLoading.dismiss();
if (fd.entries.isEmpty) { if (fd.entries.isEmpty) {
final confirm = await showRemoveDialog(translate("Are you sure you want to delete this empty directory?"), item.name, false); final confirm = await showRemoveDialog(
translate(
"Are you sure you want to delete this empty directory?"),
item.name,
false);
if (confirm == true) { if (confirm == true) {
sendRemoveEmptyDir(item.path, 0, items.isLocal!); sendRemoveEmptyDir(item.path, 0, items.isLocal!);
} }
@ -290,9 +301,10 @@ class FileModel extends ChangeNotifier {
} }
for (var i = 0; i < entries.length; i++) { for (var i = 0; i < entries.length; i++) {
final dirShow = item.isDirectory ? "${translate("Are you sure you want to delete the file of this directory?")}\n" : ""; final dirShow = item.isDirectory
final count = ? "${translate("Are you sure you want to delete the file of this directory?")}\n"
entries.length > 1 ? "${i + 1}/${entries.length}" : ""; : "";
final count = entries.length > 1 ? "${i + 1}/${entries.length}" : "";
content = dirShow + "$count \n${entries[i].path}"; content = dirShow + "$count \n${entries[i].path}";
final confirm = final confirm =
await showRemoveDialog(title, content, item.isDirectory); await showRemoveDialog(title, content, item.isDirectory);
@ -403,7 +415,7 @@ class FileModel extends ChangeNotifier {
} }
cancelJob(int id) { cancelJob(int id) {
FFI.setByName("cancel_job",id.toString()); FFI.setByName("cancel_job", id.toString());
} }
changeSortStyle(SortBy sort) { changeSortStyle(SortBy sort) {
@ -563,8 +575,6 @@ class FileDirectory {
int id = 0; int id = 0;
String path = ""; String path = "";
String get parent => p.dirname(path);
FileDirectory(); FileDirectory();
FileDirectory.fromJson(Map<String, dynamic> json) { FileDirectory.fromJson(Map<String, dynamic> json) {
@ -659,6 +669,11 @@ class PathUtil {
final pathUtil = isWindows ? windowsContext : posixContext; final pathUtil = isWindows ? windowsContext : posixContext;
return pathUtil.split(path); return pathUtil.split(path);
} }
static String dirname(String path, bool isWindows){
final pathUtil = isWindows ? windowsContext : posixContext;
return pathUtil.dirname(path);
}
} }
class DirectoryOption { class DirectoryOption {
@ -668,6 +683,12 @@ class DirectoryOption {
DirectoryOption( DirectoryOption(
{this.home = "", this.showHidden = false, this.isWindows = false}); {this.home = "", this.showHidden = false, this.isWindows = false});
clear() {
home = "";
showHidden = false;
isWindows = false;
}
} }
// code from file_manager pkg after edit // code from file_manager pkg after edit

View File

@ -235,7 +235,6 @@ class FfiModel with ChangeNotifier {
_pi.platform = evt['platform']; _pi.platform = evt['platform'];
_pi.sasEnabled = evt['sas_enabled'] == "true"; _pi.sasEnabled = evt['sas_enabled'] == "true";
_pi.currentDisplay = int.parse(evt['current_display']); _pi.currentDisplay = int.parse(evt['current_display']);
_pi.homeDir = evt['home_dir'];
if (evt['is_file_transfer'] == "true") { if (evt['is_file_transfer'] == "true") {
FFI.fileModel.onReady(); FFI.fileModel.onReady();
@ -878,7 +877,6 @@ class PeerInfo {
String username = ""; String username = "";
String hostname = ""; String hostname = "";
String platform = ""; String platform = "";
String homeDir = "";
bool sasEnabled = false; bool sasEnabled = false;
int currentDisplay = 0; int currentDisplay = 0;
List<Display> displays = []; List<Display> displays = [];

View File

@ -4,6 +4,7 @@ import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:flutter_hbb/models/file_model.dart'; import 'package:flutter_hbb/models/file_model.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:flutter_breadcrumb/flutter_breadcrumb.dart'; import 'package:flutter_breadcrumb/flutter_breadcrumb.dart';
import 'package:toggle_switch/toggle_switch.dart';
import '../common.dart'; import '../common.dart';
import '../models/model.dart'; import '../models/model.dart';
@ -58,17 +59,124 @@ class _FileManagerPageState extends State<FileManagerPage> {
backgroundColor: MyTheme.grayBg, backgroundColor: MyTheme.grayBg,
appBar: AppBar( appBar: AppBar(
leading: Row(children: [ leading: Row(children: [
IconButton(icon: Icon(Icons.arrow_back), onPressed: goBack),
IconButton(icon: Icon(Icons.close), onPressed: clientClose), IconButton(icon: Icon(Icons.close), onPressed: clientClose),
]), ]),
leadingWidth: 200,
centerTitle: true, centerTitle: true,
title: Text(translate(model.isLocal ? "Local" : "Remote")), 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: [ actions: [
IconButton( PopupMenuButton<String>(
icon: Icon(Icons.change_circle), icon: Icon(Icons.more_vert),
onPressed: () => model.togglePage(), 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: body(), body: body(),
@ -224,6 +332,10 @@ class _FileManagerPageState extends State<FileManagerPage> {
)), )),
Row( Row(
children: [ children: [
IconButton(
icon: Icon(Icons.arrow_upward),
onPressed: goBack,
),
PopupMenuButton<SortBy>( PopupMenuButton<SortBy>(
icon: Icon(Icons.sort), icon: Icon(Icons.sort),
itemBuilder: (context) { itemBuilder: (context) {
@ -236,98 +348,6 @@ class _FileManagerPageState extends State<FileManagerPage> {
.toList(); .toList();
}, },
onSelected: model.changeSortStyle), onSelected: model.changeSortStyle),
PopupMenuButton<String>(
icon: Icon(Icons.more_vert),
itemBuilder: (context) {
return [
PopupMenuItem(
child: Row(
children: [
Icon(Icons.refresh),
SizedBox(width: 5),
Text(translate("Refresh File"))
],
),
value: "refresh",
),
PopupMenuItem(
child: Row(
children: [
Icon(Icons.check),
SizedBox(width: 5),
Text(translate("Multi Select"))
],
),
value: "select",
),
PopupMenuItem(
child: Row(
children: [
Icon(Icons.folder_outlined),
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),
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();
}
}),
], ],
) )
], ],
@ -338,6 +358,13 @@ class _FileManagerPageState extends State<FileManagerPage> {
height: 100, height: 100,
child: Column( child: Column(
children: [ children: [
Padding(
padding: EdgeInsets.fromLTRB(30,5,30,0),
child: Text(
model.currentDir.path,
style: TextStyle(color: MyTheme.darkGray),
),
),
Padding( Padding(
padding: EdgeInsets.all(2), padding: EdgeInsets.all(2),
child: Text( child: Text(