Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
R
rustdesk
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
李朝发
rustdesk
Commits
235eb541
Commit
235eb541
authored
Sep 06, 2022
by
csf
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
update file transfer and adjust icon size
parent
82acb6a3
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
76 additions
and
58 deletions
+76
-58
file_manager_page.dart
flutter/lib/desktop/pages/file_manager_page.dart
+32
-19
file_model.dart
flutter/lib/models/file_model.dart
+4
-4
model.dart
flutter/lib/models/model.dart
+10
-5
client.rs
src/client.rs
+1
-0
io_loop.rs
src/client/io_loop.rs
+2
-29
flutter_ffi.rs
src/flutter_ffi.rs
+1
-1
ui_session_interface.rs
src/ui_session_interface.rs
+26
-0
No files found.
flutter/lib/desktop/pages/file_manager_page.dart
View file @
235eb541
...
@@ -59,8 +59,11 @@ class _FileManagerPageState extends State<FileManagerPage>
...
@@ -59,8 +59,11 @@ class _FileManagerPageState extends State<FileManagerPage>
super
.
initState
();
super
.
initState
();
_ffi
=
FFI
();
_ffi
=
FFI
();
_ffi
.
connect
(
widget
.
id
,
isFileTransfer:
true
);
_ffi
.
connect
(
widget
.
id
,
isFileTransfer:
true
);
WidgetsBinding
.
instance
.
addPostFrameCallback
((
_
)
{
_ffi
.
dialogManager
.
showLoading
(
translate
(
'Connecting...'
),
onCancel:
closeConnection
);
});
Get
.
put
(
_ffi
,
tag:
'ft_
${widget.id}
'
);
Get
.
put
(
_ffi
,
tag:
'ft_
${widget.id}
'
);
// _ffi.ffiModel.updateEventListener(widget.id);
if
(!
Platform
.
isLinux
)
{
if
(!
Platform
.
isLinux
)
{
Wakelock
.
enable
();
Wakelock
.
enable
();
}
}
...
@@ -117,7 +120,8 @@ class _FileManagerPageState extends State<FileManagerPage>
...
@@ -117,7 +120,8 @@ class _FileManagerPageState extends State<FileManagerPage>
Widget
menu
({
bool
isLocal
=
false
})
{
Widget
menu
({
bool
isLocal
=
false
})
{
return
PopupMenuButton
<
String
>(
return
PopupMenuButton
<
String
>(
icon:
Icon
(
Icons
.
more_vert
),
icon:
const
Icon
(
Icons
.
more_vert
),
splashRadius:
20
,
itemBuilder:
(
context
)
{
itemBuilder:
(
context
)
{
return
[
return
[
PopupMenuItem
(
PopupMenuItem
(
...
@@ -413,6 +417,7 @@ class _FileManagerPageState extends State<FileManagerPage>
...
@@ -413,6 +417,7 @@ class _FileManagerPageState extends State<FileManagerPage>
/// watch transfer status
/// watch transfer status
Widget
statusList
()
{
Widget
statusList
()
{
return
PreferredSize
(
return
PreferredSize
(
preferredSize:
const
Size
(
200
,
double
.
infinity
),
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
),
...
@@ -429,8 +434,8 @@ class _FileManagerPageState extends State<FileManagerPage>
...
@@ -429,8 +434,8 @@ class _FileManagerPageState extends State<FileManagerPage>
children:
[
children:
[
Transform
.
rotate
(
Transform
.
rotate
(
angle:
item
.
isRemote
?
pi
:
0
,
angle:
item
.
isRemote
?
pi
:
0
,
child:
Icon
(
Icons
.
send
)),
child:
const
Icon
(
Icons
.
send
)),
SizedBox
(
const
SizedBox
(
width:
16.0
,
width:
16.0
,
),
),
Expanded
(
Expanded
(
...
@@ -441,7 +446,7 @@ class _FileManagerPageState extends State<FileManagerPage>
...
@@ -441,7 +446,7 @@ class _FileManagerPageState extends State<FileManagerPage>
Tooltip
(
Tooltip
(
message:
item
.
jobName
,
message:
item
.
jobName
,
child:
Text
(
child:
Text
(
'
${item.jobName}
'
,
item
.
jobName
,
maxLines:
1
,
maxLines:
1
,
overflow:
TextOverflow
.
ellipsis
,
overflow:
TextOverflow
.
ellipsis
,
)),
)),
...
@@ -455,7 +460,7 @@ class _FileManagerPageState extends State<FileManagerPage>
...
@@ -455,7 +460,7 @@ class _FileManagerPageState extends State<FileManagerPage>
offstage:
offstage:
item
.
state
!=
JobState
.
inProgress
,
item
.
state
!=
JobState
.
inProgress
,
child:
Text
(
child:
Text
(
'
${
readableFileSize(item.speed) + "
/s"}
'
)),
'
${
"${readableFileSize(item.speed)}
/s"} '
)),
Offstage
(
Offstage
(
offstage:
item
.
totalSize
<=
0
,
offstage:
item
.
totalSize
<=
0
,
child:
Text
(
child:
Text
(
...
@@ -475,10 +480,12 @@ class _FileManagerPageState extends State<FileManagerPage>
...
@@ -475,10 +480,12 @@ class _FileManagerPageState extends State<FileManagerPage>
onPressed:
()
{
onPressed:
()
{
model
.
resumeJob
(
item
.
id
);
model
.
resumeJob
(
item
.
id
);
},
},
icon:
Icon
(
Icons
.
restart_alt_rounded
)),
splashRadius:
20
,
icon:
const
Icon
(
Icons
.
restart_alt_rounded
)),
),
),
IconButton
(
IconButton
(
icon:
Icon
(
Icons
.
delete
),
icon:
const
Icon
(
Icons
.
delete
),
splashRadius:
20
,
onPressed:
()
{
onPressed:
()
{
model
.
jobTable
.
removeAt
(
index
);
model
.
jobTable
.
removeAt
(
index
);
model
.
cancelJob
(
item
.
id
);
model
.
cancelJob
(
item
.
id
);
...
@@ -500,8 +507,7 @@ class _FileManagerPageState extends State<FileManagerPage>
...
@@ -500,8 +507,7 @@ class _FileManagerPageState extends State<FileManagerPage>
itemCount:
model
.
jobTable
.
length
,
itemCount:
model
.
jobTable
.
length
,
),
),
),
),
),
));
preferredSize:
Size
(
200
,
double
.
infinity
));
}
}
goBack
({
bool
?
isLocal
})
{
goBack
({
bool
?
isLocal
})
{
...
@@ -551,12 +557,15 @@ class _FileManagerPageState extends State<FileManagerPage>
...
@@ -551,12 +557,15 @@ class _FileManagerPageState extends State<FileManagerPage>
Row
(
Row
(
children:
[
children:
[
IconButton
(
IconButton
(
onPressed:
()
{
onPressed:
()
{
model
.
goHome
(
isLocal:
isLocal
);
model
.
goHome
(
isLocal:
isLocal
);
},
},
icon:
Icon
(
Icons
.
home_outlined
)),
icon:
const
Icon
(
Icons
.
home_outlined
),
splashRadius:
20
,
),
IconButton
(
IconButton
(
icon:
Icon
(
Icons
.
arrow_upward
),
icon:
const
Icon
(
Icons
.
arrow_upward
),
splashRadius:
20
,
onPressed:
()
{
onPressed:
()
{
goBack
(
isLocal:
isLocal
);
goBack
(
isLocal:
isLocal
);
},
},
...
@@ -622,13 +631,15 @@ class _FileManagerPageState extends State<FileManagerPage>
...
@@ -622,13 +631,15 @@ class _FileManagerPageState extends State<FileManagerPage>
),
),
))
))
],
],
child:
Icon
(
Icons
.
search
),
splashRadius:
20
,
child:
const
Icon
(
Icons
.
search
),
),
),
IconButton
(
IconButton
(
onPressed:
()
{
onPressed:
()
{
model
.
refresh
(
isLocal:
isLocal
);
model
.
refresh
(
isLocal:
isLocal
);
},
},
icon:
Icon
(
Icons
.
refresh
)),
splashRadius:
20
,
icon:
const
Icon
(
Icons
.
refresh
)),
],
],
),
),
Row
(
Row
(
...
@@ -686,6 +697,7 @@ class _FileManagerPageState extends State<FileManagerPage>
...
@@ -686,6 +697,7 @@ class _FileManagerPageState extends State<FileManagerPage>
);
);
});
});
},
},
splashRadius:
20
,
icon:
const
Icon
(
Icons
.
create_new_folder_outlined
)),
icon:
const
Icon
(
Icons
.
create_new_folder_outlined
)),
IconButton
(
IconButton
(
onPressed:
()
async
{
onPressed:
()
async
{
...
@@ -695,7 +707,8 @@ class _FileManagerPageState extends State<FileManagerPage>
...
@@ -695,7 +707,8 @@ class _FileManagerPageState extends State<FileManagerPage>
await
(
model
.
removeAction
(
items
,
isLocal:
isLocal
));
await
(
model
.
removeAction
(
items
,
isLocal:
isLocal
));
items
.
clear
();
items
.
clear
();
},
},
icon:
Icon
(
Icons
.
delete_forever_outlined
)),
splashRadius:
20
,
icon:
const
Icon
(
Icons
.
delete_forever_outlined
)),
],
],
),
),
),
),
...
@@ -707,7 +720,7 @@ class _FileManagerPageState extends State<FileManagerPage>
...
@@ -707,7 +720,7 @@ class _FileManagerPageState extends State<FileManagerPage>
},
},
icon:
Transform
.
rotate
(
icon:
Transform
.
rotate
(
angle:
isLocal
?
0
:
pi
,
angle:
isLocal
?
0
:
pi
,
child:
Icon
(
child:
const
Icon
(
Icons
.
send
,
Icons
.
send
,
),
),
),
),
...
...
flutter/lib/models/file_model.dart
View file @
235eb541
...
@@ -360,9 +360,9 @@ class FileModel extends ChangeNotifier {
...
@@ -360,9 +360,9 @@ class FileModel extends ChangeNotifier {
Future
refresh
({
bool
?
isLocal
})
async
{
Future
refresh
({
bool
?
isLocal
})
async
{
if
(
isDesktop
)
{
if
(
isDesktop
)
{
isLocal
=
isLocal
??
_isLocal
;
isLocal
=
isLocal
??
_isLocal
;
await
isLocal
isLocal
?
openDirectory
(
currentLocalDir
.
path
,
isLocal:
isLocal
)
?
await
openDirectory
(
currentLocalDir
.
path
,
isLocal:
isLocal
)
:
openDirectory
(
currentRemoteDir
.
path
,
isLocal:
isLocal
);
:
await
openDirectory
(
currentRemoteDir
.
path
,
isLocal:
isLocal
);
}
else
{
}
else
{
await
openDirectory
(
currentDir
.
path
);
await
openDirectory
(
currentDir
.
path
);
}
}
...
@@ -393,7 +393,7 @@ class FileModel extends ChangeNotifier {
...
@@ -393,7 +393,7 @@ class FileModel extends ChangeNotifier {
}
}
notifyListeners
();
notifyListeners
();
}
catch
(
e
)
{
}
catch
(
e
)
{
debugPrint
(
"Failed to openDirectory
$
{path}
:
$e
"
);
debugPrint
(
"Failed to openDirectory
$
path
:
$e
"
);
}
}
}
}
...
...
flutter/lib/models/model.dart
View file @
235eb541
...
@@ -326,8 +326,8 @@ class FfiModel with ChangeNotifier {
...
@@ -326,8 +326,8 @@ class FfiModel with ChangeNotifier {
await
bind
.
sessionGetOption
(
id:
peerId
,
arg:
"touch-mode"
)
!=
''
;
await
bind
.
sessionGetOption
(
id:
peerId
,
arg:
"touch-mode"
)
!=
''
;
}
}
if
(
evt
[
'is_file_transfer'
]
==
"true"
)
{
if
(
parent
.
target
!=
null
&&
// TODO is file transfer
parent
.
target
!.
connType
==
ConnType
.
fileTransfer
)
{
parent
.
target
?.
fileModel
.
onReady
();
parent
.
target
?.
fileModel
.
onReady
();
}
else
{
}
else
{
_pi
.
displays
=
[];
_pi
.
displays
=
[];
...
@@ -916,6 +916,8 @@ extension ToString on MouseButtons {
...
@@ -916,6 +916,8 @@ extension ToString on MouseButtons {
}
}
}
}
enum
ConnType
{
defaultConn
,
fileTransfer
,
portForward
,
rdp
}
/// FFI class for communicating with the Rust core.
/// FFI class for communicating with the Rust core.
class
FFI
{
class
FFI
{
var
id
=
""
;
var
id
=
""
;
...
@@ -924,6 +926,7 @@ class FFI {
...
@@ -924,6 +926,7 @@ class FFI {
var
alt
=
false
;
var
alt
=
false
;
var
command
=
false
;
var
command
=
false
;
var
version
=
""
;
var
version
=
""
;
var
connType
=
ConnType
.
defaultConn
;
/// dialogManager use late to ensure init after main page binding [globalKey]
/// dialogManager use late to ensure init after main page binding [globalKey]
late
final
dialogManager
=
OverlayDialogManager
();
late
final
dialogManager
=
OverlayDialogManager
();
...
@@ -1055,9 +1058,11 @@ class FFI {
...
@@ -1055,9 +1058,11 @@ class FFI {
double
tabBarHeight
=
0.0
})
{
double
tabBarHeight
=
0.0
})
{
assert
(!(
isFileTransfer
&&
isPortForward
),
"more than one connect type"
);
assert
(!(
isFileTransfer
&&
isPortForward
),
"more than one connect type"
);
if
(
isFileTransfer
)
{
if
(
isFileTransfer
)
{
id
=
'ft_
${id}
'
;
connType
=
ConnType
.
fileTransfer
;
id
=
'ft_
$id
'
;
}
else
if
(
isPortForward
)
{
}
else
if
(
isPortForward
)
{
id
=
'pf_
${id}
'
;
connType
=
ConnType
.
portForward
;
id
=
'pf_
$id
'
;
}
else
{
}
else
{
chatModel
.
resetClientMode
();
chatModel
.
resetClientMode
();
canvasModel
.
id
=
id
;
canvasModel
.
id
=
id
;
...
@@ -1086,7 +1091,7 @@ class FFI {
...
@@ -1086,7 +1091,7 @@ class FFI {
// every instance will bind a stream
// every instance will bind a stream
this
.
id
=
id
;
this
.
id
=
id
;
if
(
isFileTransfer
)
{
if
(
isFileTransfer
)
{
this
.
fileModel
.
initFileFetcher
();
fileModel
.
initFileFetcher
();
}
}
}
}
...
...
src/client.rs
View file @
235eb541
...
@@ -1665,6 +1665,7 @@ pub async fn handle_login_from_ui(
...
@@ -1665,6 +1665,7 @@ pub async fn handle_login_from_ui(
/// Interface for client to send data and commands.
/// Interface for client to send data and commands.
#[async_trait]
#[async_trait]
pub
trait
Interface
:
Send
+
Clone
+
'static
+
Sized
{
pub
trait
Interface
:
Send
+
Clone
+
'static
+
Sized
{
/// Send message data to remote peer.
fn
send
(
&
self
,
data
:
Data
);
fn
send
(
&
self
,
data
:
Data
);
fn
msgbox
(
&
self
,
msgtype
:
&
str
,
title
:
&
str
,
text
:
&
str
);
fn
msgbox
(
&
self
,
msgtype
:
&
str
,
title
:
&
str
,
text
:
&
str
);
fn
handle_login_error
(
&
mut
self
,
err
:
&
str
)
->
bool
;
fn
handle_login_error
(
&
mut
self
,
err
:
&
str
)
->
bool
;
...
...
src/client/io_loop.rs
View file @
235eb541
...
@@ -269,33 +269,6 @@ impl<T: InvokeUiSession> Remote<T> {
...
@@ -269,33 +269,6 @@ impl<T: InvokeUiSession> Remote<T> {
Some
(
tx
)
Some
(
tx
)
}
}
// TODO
fn
load_last_jobs
(
&
mut
self
)
{
self
.handler
.clear_all_jobs
();
let
pc
=
self
.handler
.load_config
();
if
pc
.transfer.write_jobs
.is_empty
()
&&
pc
.transfer.read_jobs
.is_empty
()
{
// no last jobs
return
;
}
// TODO: can add a confirm dialog
let
mut
cnt
=
1
;
for
job_str
in
pc
.transfer.read_jobs
.iter
()
{
if
!
job_str
.is_empty
()
{
self
.handler
.load_last_job
(
cnt
,
job_str
);
cnt
+=
1
;
log
::
info!
(
"restore read_job: {:?}"
,
job_str
);
}
}
for
job_str
in
pc
.transfer.write_jobs
.iter
()
{
if
!
job_str
.is_empty
()
{
self
.handler
.load_last_job
(
cnt
,
job_str
);
cnt
+=
1
;
log
::
info!
(
"restore write_job: {:?}"
,
job_str
);
}
}
self
.handler
.update_transfer_list
();
}
async
fn
handle_msg_from_ui
(
&
mut
self
,
data
:
Data
,
peer
:
&
mut
Stream
)
->
bool
{
async
fn
handle_msg_from_ui
(
&
mut
self
,
data
:
Data
,
peer
:
&
mut
Stream
)
->
bool
{
match
data
{
match
data
{
Data
::
Close
=>
{
Data
::
Close
=>
{
...
@@ -768,7 +741,7 @@ impl<T: InvokeUiSession> Remote<T> {
...
@@ -768,7 +741,7 @@ impl<T: InvokeUiSession> Remote<T> {
}
}
if
self
.handler
.is_file_transfer
()
{
if
self
.handler
.is_file_transfer
()
{
self
.load_last_jobs
();
self
.
handler
.
load_last_jobs
();
}
}
}
}
_
=>
{}
_
=>
{}
...
@@ -827,7 +800,7 @@ impl<T: InvokeUiSession> Remote<T> {
...
@@ -827,7 +800,7 @@ impl<T: InvokeUiSession> Remote<T> {
&
entries
,
&
entries
,
fd
.path
,
fd
.path
,
false
,
false
,
f
d
.id
>
0
,
f
alse
,
);
);
if
let
Some
(
job
)
=
fs
::
get_job
(
fd
.id
,
&
mut
self
.write_jobs
)
{
if
let
Some
(
job
)
=
fs
::
get_job
(
fd
.id
,
&
mut
self
.write_jobs
)
{
log
::
info!
(
"job set_files: {:?}"
,
entries
);
log
::
info!
(
"job set_files: {:?}"
,
entries
);
...
...
src/flutter_ffi.rs
View file @
235eb541
...
@@ -366,7 +366,7 @@ pub fn session_get_platform(id: String, is_remote: bool) -> String {
...
@@ -366,7 +366,7 @@ pub fn session_get_platform(id: String, is_remote: bool) -> String {
pub
fn
session_load_last_transfer_jobs
(
id
:
String
)
{
pub
fn
session_load_last_transfer_jobs
(
id
:
String
)
{
if
let
Some
(
session
)
=
SESSIONS
.read
()
.unwrap
()
.get
(
&
id
)
{
if
let
Some
(
session
)
=
SESSIONS
.read
()
.unwrap
()
.get
(
&
id
)
{
//
return session.load_last_jobs();
return
session
.load_last_jobs
();
}
else
{
}
else
{
// a tip for flutter dev
// a tip for flutter dev
eprintln!
(
eprintln!
(
...
...
src/ui_session_interface.rs
View file @
235eb541
...
@@ -532,6 +532,32 @@ impl<T: InvokeUiSession> Session<T> {
...
@@ -532,6 +532,32 @@ impl<T: InvokeUiSession> Session<T> {
pub
fn
close
(
&
self
)
{
pub
fn
close
(
&
self
)
{
self
.send
(
Data
::
Close
);
self
.send
(
Data
::
Close
);
}
}
pub
fn
load_last_jobs
(
&
self
)
{
self
.clear_all_jobs
();
let
pc
=
self
.load_config
();
if
pc
.transfer.write_jobs
.is_empty
()
&&
pc
.transfer.read_jobs
.is_empty
()
{
// no last jobs
return
;
}
// TODO: can add a confirm dialog
let
mut
cnt
=
1
;
for
job_str
in
pc
.transfer.read_jobs
.iter
()
{
if
!
job_str
.is_empty
()
{
self
.load_last_job
(
cnt
,
job_str
);
cnt
+=
1
;
log
::
info!
(
"restore read_job: {:?}"
,
job_str
);
}
}
for
job_str
in
pc
.transfer.write_jobs
.iter
()
{
if
!
job_str
.is_empty
()
{
self
.load_last_job
(
cnt
,
job_str
);
cnt
+=
1
;
log
::
info!
(
"restore write_job: {:?}"
,
job_str
);
}
}
self
.update_transfer_list
();
}
}
}
pub
trait
InvokeUiSession
:
Send
+
Sync
+
Clone
+
'static
+
Sized
+
Default
{
pub
trait
InvokeUiSession
:
Send
+
Sync
+
Clone
+
'static
+
Sized
+
Default
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment