fix: file transfer, auto start on reconnect (#13329)

Signed-off-by: fufesou <linlong1266@gmail.com>
This commit is contained in:
fufesou
2025-10-29 15:15:05 +08:00
committed by GitHub
parent 265d08fc3b
commit e3fcc6cce3
6 changed files with 119 additions and 30 deletions

View File

@@ -29,7 +29,10 @@ use std::{
collections::HashMap,
ops::{Deref, DerefMut},
str::FromStr,
sync::{Arc, Mutex, RwLock},
sync::{
atomic::{AtomicUsize, Ordering},
Arc, Mutex, RwLock,
},
time::SystemTime,
};
use uuid::Uuid;
@@ -61,6 +64,9 @@ pub struct Session<T: InvokeUiSession> {
pub last_change_display: Arc<Mutex<ChangeDisplayRecord>>,
pub connection_round_state: Arc<Mutex<ConnectionRoundState>>,
pub printer_names: Arc<RwLock<HashMap<i32, String>>>,
// Indicate whether the session is reconnected.
// Used to auto start file transfer after reconnection.
pub reconnect_count: Arc<AtomicUsize>,
}
#[derive(Clone)]
@@ -1272,6 +1278,7 @@ impl<T: InvokeUiSession> Session<T> {
self.lc.write().unwrap().force_relay = true;
}
self.lc.write().unwrap().peer_info = None;
self.reconnect_count.fetch_add(1, Ordering::SeqCst);
let mut lock = self.thread.lock().unwrap();
// No need to join the previous thread, because it will exit automatically.
// And the previous thread will not change important states.
@@ -1372,6 +1379,24 @@ impl<T: InvokeUiSession> Session<T> {
self.send(Data::Close);
}
fn try_auto_start_job_str(is_reconnected: bool, job_str: &str) -> Option<String> {
if is_reconnected {
let job_str = job_str.trim();
if let Some(stripped) = job_str.strip_suffix('}') {
format!(r#"{},"auto_start": true}}"#, stripped).into()
} else {
// unreachable in normal cases
log::warn!(
"The last character is not '}}': {}, auto start is ignored on flutter",
job_str
);
Some(job_str.to_owned())
}
} else {
None
}
}
pub fn load_last_jobs(&self) {
self.clear_all_jobs();
let pc = self.load_config();
@@ -1379,18 +1404,32 @@ impl<T: InvokeUiSession> Session<T> {
// no last jobs
return;
}
let reconnect_count_thr = if cfg!(feature = "flutter") { 0 } else { 1 };
let is_reconnected = self.reconnect_count.load(Ordering::SeqCst) > reconnect_count_thr;
// 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);
self.load_last_job(
cnt,
Self::try_auto_start_job_str(is_reconnected, job_str)
.as_deref()
.unwrap_or(job_str),
is_reconnected,
);
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);
self.load_last_job(
cnt,
Self::try_auto_start_job_str(is_reconnected, job_str)
.as_deref()
.unwrap_or(job_str),
is_reconnected,
);
cnt += 1;
log::info!("restore write_job: {:?}", job_str);
}
@@ -1623,7 +1662,7 @@ pub trait InvokeUiSession: Send + Sync + Clone + 'static + Sized + Default {
fn clear_all_jobs(&self);
fn new_message(&self, msg: String);
fn update_transfer_list(&self);
fn load_last_job(&self, cnt: i32, job_json: &str);
fn load_last_job(&self, cnt: i32, job_json: &str, auto_start: bool);
fn update_folder_files(
&self,
id: i32,