Merge pull request #4817 from 21pages/relay
opt force_relay/relay_hint logic
This commit is contained in:
commit
7408a4b5e6
@ -350,7 +350,7 @@ class FfiModel with ChangeNotifier {
|
|||||||
} else if (type == 'elevation-error') {
|
} else if (type == 'elevation-error') {
|
||||||
showElevationError(sessionId, type, title, text, dialogManager);
|
showElevationError(sessionId, type, title, text, dialogManager);
|
||||||
} else if (type == 'relay-hint') {
|
} else if (type == 'relay-hint') {
|
||||||
showRelayHintDialog(sessionId, type, title, text, dialogManager);
|
showRelayHintDialog(sessionId, type, title, text, dialogManager, peerId);
|
||||||
} else {
|
} else {
|
||||||
var hasRetry = evt['hasRetry'] == 'true';
|
var hasRetry = evt['hasRetry'] == 'true';
|
||||||
showMsgBox(sessionId, type, title, text, link, hasRetry, dialogManager);
|
showMsgBox(sessionId, type, title, text, link, hasRetry, dialogManager);
|
||||||
@ -383,7 +383,7 @@ class FfiModel with ChangeNotifier {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void showRelayHintDialog(SessionID sessionId, String type, String title,
|
void showRelayHintDialog(SessionID sessionId, String type, String title,
|
||||||
String text, OverlayDialogManager dialogManager) {
|
String text, OverlayDialogManager dialogManager, String peerId) {
|
||||||
dialogManager.show(tag: '$sessionId-$type', (setState, close, context) {
|
dialogManager.show(tag: '$sessionId-$type', (setState, close, context) {
|
||||||
onClose() {
|
onClose() {
|
||||||
closeConnection();
|
closeConnection();
|
||||||
@ -392,25 +392,24 @@ class FfiModel with ChangeNotifier {
|
|||||||
|
|
||||||
final style =
|
final style =
|
||||||
ElevatedButton.styleFrom(backgroundColor: Colors.green[700]);
|
ElevatedButton.styleFrom(backgroundColor: Colors.green[700]);
|
||||||
|
var hint = "\n\n${translate('relay_hint_tip')}";
|
||||||
|
if (text.contains("10054") || text.contains("104")) {
|
||||||
|
hint = "";
|
||||||
|
}
|
||||||
|
final alreadyForceAlwaysRelay = bind
|
||||||
|
.mainGetPeerOptionSync(id: peerId, key: 'force-always-relay')
|
||||||
|
.isNotEmpty;
|
||||||
return CustomAlertDialog(
|
return CustomAlertDialog(
|
||||||
title: null,
|
title: null,
|
||||||
content: msgboxContent(type, title,
|
content: msgboxContent(type, title, "${translate(text)}$hint"),
|
||||||
"${translate(text)}\n\n${translate('relay_hint_tip')}"),
|
|
||||||
actions: [
|
actions: [
|
||||||
dialogButton('Close', onPressed: onClose, isOutline: true),
|
dialogButton('Close', onPressed: onClose, isOutline: true),
|
||||||
dialogButton('Retry',
|
dialogButton('Retry',
|
||||||
onPressed: () => reconnect(dialogManager, sessionId, false)),
|
onPressed: () => reconnect(dialogManager, sessionId, false)),
|
||||||
dialogButton('Connect via relay',
|
if (!alreadyForceAlwaysRelay)
|
||||||
onPressed: () => reconnect(dialogManager, sessionId, true),
|
dialogButton('Connect via relay',
|
||||||
buttonStyle: style),
|
onPressed: () => reconnect(dialogManager, sessionId, true),
|
||||||
dialogButton('Always connect via relay', onPressed: () {
|
buttonStyle: style),
|
||||||
const option = 'force-always-relay';
|
|
||||||
bind.sessionPeerOption(
|
|
||||||
sessionId: sessionId,
|
|
||||||
name: option,
|
|
||||||
value: bool2option(option, true));
|
|
||||||
reconnect(dialogManager, sessionId, true);
|
|
||||||
}, buttonStyle: style),
|
|
||||||
],
|
],
|
||||||
onCancel: onClose,
|
onCancel: onClose,
|
||||||
);
|
);
|
||||||
|
@ -213,6 +213,8 @@ impl Client {
|
|||||||
conn_type: ConnType,
|
conn_type: ConnType,
|
||||||
interface: impl Interface,
|
interface: impl Interface,
|
||||||
) -> ResultType<(Stream, bool, Option<Vec<u8>>)> {
|
) -> ResultType<(Stream, bool, Option<Vec<u8>>)> {
|
||||||
|
interface.update_direct(None);
|
||||||
|
interface.update_received(false);
|
||||||
match Self::_start(peer, key, token, conn_type, interface).await {
|
match Self::_start(peer, key, token, conn_type, interface).await {
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
let err_str = err.to_string();
|
let err_str = err.to_string();
|
||||||
@ -353,15 +355,8 @@ impl Client {
|
|||||||
my_addr.is_ipv4(),
|
my_addr.is_ipv4(),
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
let pk = Self::secure_connection(
|
let pk =
|
||||||
peer,
|
Self::secure_connection(peer, signed_id_pk, key, &mut conn).await?;
|
||||||
signed_id_pk,
|
|
||||||
key,
|
|
||||||
&mut conn,
|
|
||||||
false,
|
|
||||||
interface,
|
|
||||||
)
|
|
||||||
.await?;
|
|
||||||
return Ok((conn, false, pk));
|
return Ok((conn, false, pk));
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
@ -459,6 +454,7 @@ impl Client {
|
|||||||
let mut conn =
|
let mut conn =
|
||||||
socket_client::connect_tcp_local(peer, Some(local_addr), connect_timeout).await;
|
socket_client::connect_tcp_local(peer, Some(local_addr), connect_timeout).await;
|
||||||
let mut direct = !conn.is_err();
|
let mut direct = !conn.is_err();
|
||||||
|
interface.update_direct(Some(direct));
|
||||||
if interface.is_force_relay() || conn.is_err() {
|
if interface.is_force_relay() || conn.is_err() {
|
||||||
if !relay_server.is_empty() {
|
if !relay_server.is_empty() {
|
||||||
conn = Self::request_relay(
|
conn = Self::request_relay(
|
||||||
@ -471,6 +467,7 @@ impl Client {
|
|||||||
conn_type,
|
conn_type,
|
||||||
)
|
)
|
||||||
.await;
|
.await;
|
||||||
|
interface.update_direct(Some(false));
|
||||||
if conn.is_err() {
|
if conn.is_err() {
|
||||||
bail!(
|
bail!(
|
||||||
"Failed to connect via relay server: {}",
|
"Failed to connect via relay server: {}",
|
||||||
@ -490,8 +487,7 @@ impl Client {
|
|||||||
}
|
}
|
||||||
let mut conn = conn?;
|
let mut conn = conn?;
|
||||||
log::info!("{:?} used to establish connection", start.elapsed());
|
log::info!("{:?} used to establish connection", start.elapsed());
|
||||||
let pk = Self::secure_connection(peer_id, signed_id_pk, key, &mut conn, direct, interface)
|
let pk = Self::secure_connection(peer_id, signed_id_pk, key, &mut conn).await?;
|
||||||
.await?;
|
|
||||||
Ok((conn, direct, pk))
|
Ok((conn, direct, pk))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -501,8 +497,6 @@ impl Client {
|
|||||||
signed_id_pk: Vec<u8>,
|
signed_id_pk: Vec<u8>,
|
||||||
key: &str,
|
key: &str,
|
||||||
conn: &mut Stream,
|
conn: &mut Stream,
|
||||||
direct: bool,
|
|
||||||
interface: impl Interface,
|
|
||||||
) -> ResultType<Option<Vec<u8>>> {
|
) -> ResultType<Option<Vec<u8>>> {
|
||||||
let rs_pk = get_rs_pk(if key.is_empty() {
|
let rs_pk = get_rs_pk(if key.is_empty() {
|
||||||
hbb_common::config::RS_PUB_KEY
|
hbb_common::config::RS_PUB_KEY
|
||||||
@ -532,13 +526,7 @@ impl Client {
|
|||||||
};
|
};
|
||||||
match timeout(READ_TIMEOUT, conn.next()).await? {
|
match timeout(READ_TIMEOUT, conn.next()).await? {
|
||||||
Some(res) => {
|
Some(res) => {
|
||||||
let bytes = match res {
|
let bytes = res?;
|
||||||
Ok(bytes) => bytes,
|
|
||||||
Err(err) => {
|
|
||||||
interface.set_force_relay(direct, false, err.to_string());
|
|
||||||
bail!("{}", err);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
if let Ok(msg_in) = Message::parse_from_bytes(&bytes) {
|
if let Ok(msg_in) = Message::parse_from_bytes(&bytes) {
|
||||||
if let Some(message::Union::SignedId(si)) = msg_in.union {
|
if let Some(message::Union::SignedId(si)) = msg_in.union {
|
||||||
if let Ok((id, their_pk_b)) = decode_id_pk(&si.id, &sign_pk) {
|
if let Ok((id, their_pk_b)) = decode_id_pk(&si.id, &sign_pk) {
|
||||||
@ -1081,8 +1069,6 @@ pub struct LoginConfigHandler {
|
|||||||
pub direct: Option<bool>,
|
pub direct: Option<bool>,
|
||||||
pub received: bool,
|
pub received: bool,
|
||||||
switch_uuid: Option<String>,
|
switch_uuid: Option<String>,
|
||||||
pub success_time: Option<hbb_common::tokio::time::Instant>,
|
|
||||||
pub direct_error_counter: usize,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Deref for LoginConfigHandler {
|
impl Deref for LoginConfigHandler {
|
||||||
@ -1133,8 +1119,6 @@ impl LoginConfigHandler {
|
|||||||
self.direct = None;
|
self.direct = None;
|
||||||
self.received = false;
|
self.received = false;
|
||||||
self.switch_uuid = switch_uuid;
|
self.switch_uuid = switch_uuid;
|
||||||
self.success_time = None;
|
|
||||||
self.direct_error_counter = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Check if the client should auto login.
|
/// Check if the client should auto login.
|
||||||
@ -1761,20 +1745,6 @@ impl LoginConfigHandler {
|
|||||||
msg_out.set_misc(misc);
|
msg_out.set_misc(misc);
|
||||||
msg_out
|
msg_out
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_force_relay(&mut self, direct: bool, received: bool, err: String) {
|
|
||||||
self.force_relay = false;
|
|
||||||
if direct && !received {
|
|
||||||
let errno = errno::errno().0;
|
|
||||||
// TODO: check mac and ios
|
|
||||||
if cfg!(windows) && (errno == 10054 || err.contains("10054"))
|
|
||||||
|| !cfg!(windows) && (errno == 104 || err.contains("104"))
|
|
||||||
{
|
|
||||||
self.force_relay = true;
|
|
||||||
self.set_option("force-always-relay".to_owned(), "Y".to_owned());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Media data.
|
/// Media data.
|
||||||
@ -2319,16 +2289,48 @@ pub trait Interface: Send + Clone + 'static + Sized {
|
|||||||
async fn handle_test_delay(&mut self, t: TestDelay, peer: &mut Stream);
|
async fn handle_test_delay(&mut self, t: TestDelay, peer: &mut Stream);
|
||||||
|
|
||||||
fn get_login_config_handler(&self) -> Arc<RwLock<LoginConfigHandler>>;
|
fn get_login_config_handler(&self) -> Arc<RwLock<LoginConfigHandler>>;
|
||||||
fn set_force_relay(&self, direct: bool, received: bool, err: String) {
|
|
||||||
self.get_login_config_handler()
|
|
||||||
.write()
|
|
||||||
.unwrap()
|
|
||||||
.set_force_relay(direct, received, err);
|
|
||||||
}
|
|
||||||
fn is_force_relay(&self) -> bool {
|
fn is_force_relay(&self) -> bool {
|
||||||
self.get_login_config_handler().read().unwrap().force_relay
|
self.get_login_config_handler().read().unwrap().force_relay
|
||||||
}
|
}
|
||||||
fn swap_modifier_mouse(&self, _msg: &mut hbb_common::protos::message::MouseEvent) {}
|
fn swap_modifier_mouse(&self, _msg: &mut hbb_common::protos::message::MouseEvent) {}
|
||||||
|
|
||||||
|
fn update_direct(&self, direct: Option<bool>) {
|
||||||
|
self.get_login_config_handler().write().unwrap().direct = direct;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn update_received(&self, received: bool) {
|
||||||
|
self.get_login_config_handler().write().unwrap().received = received;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn on_establish_connection_error(&self, err: String) {
|
||||||
|
log::error!("Connection closed: {}", err);
|
||||||
|
let title = "Connection Error";
|
||||||
|
let text = err.to_string();
|
||||||
|
let lc = self.get_login_config_handler();
|
||||||
|
let direct = lc.read().unwrap().direct;
|
||||||
|
let received = lc.read().unwrap().received;
|
||||||
|
let relay_condition = direct == Some(true) && !received;
|
||||||
|
|
||||||
|
// force relay
|
||||||
|
let errno = errno::errno().0;
|
||||||
|
if relay_condition
|
||||||
|
&& (cfg!(windows) && (errno == 10054 || err.contains("10054"))
|
||||||
|
|| !cfg!(windows) && (errno == 104 || err.contains("104")))
|
||||||
|
{
|
||||||
|
lc.write().unwrap().force_relay = true;
|
||||||
|
lc.write()
|
||||||
|
.unwrap()
|
||||||
|
.set_option("force-always-relay".to_owned(), "Y".to_owned());
|
||||||
|
}
|
||||||
|
|
||||||
|
// relay-hint
|
||||||
|
if cfg!(feature = "flutter") && relay_condition {
|
||||||
|
self.msgbox("relay-hint", title, &text, "");
|
||||||
|
} else {
|
||||||
|
self.msgbox("error", title, &text, "");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Data used by the client interface.
|
/// Data used by the client interface.
|
||||||
|
@ -124,7 +124,7 @@ impl<T: InvokeUiSession> Remote<T> {
|
|||||||
{
|
{
|
||||||
Ok((mut peer, direct, pk)) => {
|
Ok((mut peer, direct, pk)) => {
|
||||||
self.handler.set_connection_type(peer.is_secured(), direct); // flutter -> connection_ready
|
self.handler.set_connection_type(peer.is_secured(), direct); // flutter -> connection_ready
|
||||||
self.handler.set_connection_info(direct, false);
|
self.handler.update_direct(Some(direct));
|
||||||
if conn_type == ConnType::DEFAULT_CONN {
|
if conn_type == ConnType::DEFAULT_CONN {
|
||||||
self.handler
|
self.handler
|
||||||
.set_fingerprint(crate::common::pk_to_fingerprint(pk.unwrap_or_default()));
|
.set_fingerprint(crate::common::pk_to_fingerprint(pk.unwrap_or_default()));
|
||||||
@ -160,24 +160,14 @@ impl<T: InvokeUiSession> Remote<T> {
|
|||||||
if let Some(res) = res {
|
if let Some(res) = res {
|
||||||
match res {
|
match res {
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
log::error!("Connection closed: {}", err);
|
self.handler.on_establish_connection_error(err.to_string());
|
||||||
self.handler.set_force_relay(direct, received, err.to_string());
|
|
||||||
let msgtype = "error";
|
|
||||||
let title = "Connection Error";
|
|
||||||
let text = err.to_string();
|
|
||||||
let show_relay_hint = self.handler.show_relay_hint(last_recv_time, msgtype, title, &text);
|
|
||||||
if show_relay_hint{
|
|
||||||
self.handler.msgbox("relay-hint", title, &text, "");
|
|
||||||
} else {
|
|
||||||
self.handler.msgbox(msgtype, title, &text, "");
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
Ok(ref bytes) => {
|
Ok(ref bytes) => {
|
||||||
last_recv_time = Instant::now();
|
last_recv_time = Instant::now();
|
||||||
if !received {
|
if !received {
|
||||||
received = true;
|
received = true;
|
||||||
self.handler.set_connection_info(direct, true);
|
self.handler.update_received(true);
|
||||||
}
|
}
|
||||||
self.data_count.fetch_add(bytes.len(), Ordering::Relaxed);
|
self.data_count.fetch_add(bytes.len(), Ordering::Relaxed);
|
||||||
if !self.handle_msg_from_peer(bytes, &mut peer).await {
|
if !self.handle_msg_from_peer(bytes, &mut peer).await {
|
||||||
@ -271,8 +261,7 @@ impl<T: InvokeUiSession> Remote<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
self.handler
|
self.handler.on_establish_connection_error(err.to_string());
|
||||||
.msgbox("error", "Connection Error", &err.to_string(), "");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
||||||
|
@ -44,7 +44,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
|||||||
("wait_accept_uac_tip", "Please wait for the remote user to accept the UAC dialog."),
|
("wait_accept_uac_tip", "Please wait for the remote user to accept the UAC dialog."),
|
||||||
("still_click_uac_tip", "Still requires the remote user to click OK on the UAC window of running RustDesk."),
|
("still_click_uac_tip", "Still requires the remote user to click OK on the UAC window of running RustDesk."),
|
||||||
("config_microphone", "In order to speak remotely, you need to grant RustDesk \"Record Audio\" permissions."),
|
("config_microphone", "In order to speak remotely, you need to grant RustDesk \"Record Audio\" permissions."),
|
||||||
("relay_hint_tip", "It may not be possible to connect directly, you can try to connect via relay. \nIn addition, if you want to use relay on your first try, you can add the \"/r\" suffix to the ID, or select the option \"Always connect via relay\" in the peer card."),
|
("relay_hint_tip", "It may not be possible to connect directly; you can try connecting via relay. Additionally, if you want to use a relay on your first attempt, you can add the \"/r\" suffix to the ID or select the option \"Always connect via relay\" in the card of recent sessions."),
|
||||||
("No transfers in progress", ""),
|
("No transfers in progress", ""),
|
||||||
("idd_driver_tip", "Install virtual display driver which is used when you have no physical displays."),
|
("idd_driver_tip", "Install virtual display driver which is used when you have no physical displays."),
|
||||||
("confirm_idd_driver_tip", "The option to install the virtual display driver is checked. Note that a test certificate will be installed to trust the virtual display driver. This test certificate will only be used to trust Rustdesk drivers."),
|
("confirm_idd_driver_tip", "The option to install the virtual display driver is checked. Note that a test certificate will be installed to trust the virtual display driver. This test certificate will only be used to trust Rustdesk drivers."),
|
||||||
|
@ -81,7 +81,7 @@ pub async fn listen(
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
interface.msgbox("error", "Error", &err.to_string(), "");
|
interface.on_establish_connection_error(err.to_string());
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
@ -112,43 +112,6 @@ async fn connect_and_login(
|
|||||||
key: &str,
|
key: &str,
|
||||||
token: &str,
|
token: &str,
|
||||||
is_rdp: bool,
|
is_rdp: bool,
|
||||||
) -> ResultType<Option<Stream>> {
|
|
||||||
let mut res = connect_and_login_2(
|
|
||||||
id,
|
|
||||||
password,
|
|
||||||
ui_receiver,
|
|
||||||
interface.clone(),
|
|
||||||
forward,
|
|
||||||
key,
|
|
||||||
token,
|
|
||||||
is_rdp,
|
|
||||||
)
|
|
||||||
.await;
|
|
||||||
if res.is_err() && interface.is_force_relay() {
|
|
||||||
res = connect_and_login_2(
|
|
||||||
id,
|
|
||||||
password,
|
|
||||||
ui_receiver,
|
|
||||||
interface,
|
|
||||||
forward,
|
|
||||||
key,
|
|
||||||
token,
|
|
||||||
is_rdp,
|
|
||||||
)
|
|
||||||
.await;
|
|
||||||
}
|
|
||||||
res
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn connect_and_login_2(
|
|
||||||
id: &str,
|
|
||||||
password: &str,
|
|
||||||
ui_receiver: &mut mpsc::UnboundedReceiver<Data>,
|
|
||||||
interface: impl Interface,
|
|
||||||
forward: &mut Framed<TcpStream, BytesCodec>,
|
|
||||||
key: &str,
|
|
||||||
token: &str,
|
|
||||||
is_rdp: bool,
|
|
||||||
) -> ResultType<Option<Stream>> {
|
) -> ResultType<Option<Stream>> {
|
||||||
let conn_type = if is_rdp {
|
let conn_type = if is_rdp {
|
||||||
ConnType::RDP
|
ConnType::RDP
|
||||||
@ -157,6 +120,7 @@ async fn connect_and_login_2(
|
|||||||
};
|
};
|
||||||
let (mut stream, direct, _pk) =
|
let (mut stream, direct, _pk) =
|
||||||
Client::start(id, key, token, conn_type, interface.clone()).await?;
|
Client::start(id, key, token, conn_type, interface.clone()).await?;
|
||||||
|
interface.update_direct(Some(direct));
|
||||||
let mut interface = interface;
|
let mut interface = interface;
|
||||||
let mut buffer = Vec::new();
|
let mut buffer = Vec::new();
|
||||||
let mut received = false;
|
let mut received = false;
|
||||||
@ -167,7 +131,10 @@ async fn connect_and_login_2(
|
|||||||
bail!("Timeout");
|
bail!("Timeout");
|
||||||
}
|
}
|
||||||
Ok(Some(Ok(bytes))) => {
|
Ok(Some(Ok(bytes))) => {
|
||||||
received = true;
|
if !received {
|
||||||
|
received = true;
|
||||||
|
interface.update_received(true);
|
||||||
|
}
|
||||||
let msg_in = Message::parse_from_bytes(&bytes)?;
|
let msg_in = Message::parse_from_bytes(&bytes)?;
|
||||||
match msg_in.union {
|
match msg_in.union {
|
||||||
Some(message::Union::Hash(hash)) => {
|
Some(message::Union::Hash(hash)) => {
|
||||||
@ -191,8 +158,6 @@ async fn connect_and_login_2(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(Some(Err(err))) => {
|
Ok(Some(Err(err))) => {
|
||||||
log::error!("Connection closed: {}", err);
|
|
||||||
interface.set_force_relay(direct, received, err.to_string());
|
|
||||||
bail!("Connection closed: {}", err);
|
bail!("Connection closed: {}", err);
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
|
@ -146,12 +146,6 @@ impl<T: InvokeUiSession> Session<T> {
|
|||||||
self.lc.read().unwrap().conn_type.eq(&ConnType::RDP)
|
self.lc.read().unwrap().conn_type.eq(&ConnType::RDP)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_connection_info(&mut self, direct: bool, received: bool) {
|
|
||||||
let mut lc = self.lc.write().unwrap();
|
|
||||||
lc.direct = Some(direct);
|
|
||||||
lc.received = received;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_view_style(&self) -> String {
|
pub fn get_view_style(&self) -> String {
|
||||||
self.lc.read().unwrap().view_style.clone()
|
self.lc.read().unwrap().view_style.clone()
|
||||||
}
|
}
|
||||||
@ -940,38 +934,6 @@ impl<T: InvokeUiSession> Session<T> {
|
|||||||
pub fn close_voice_call(&self) {
|
pub fn close_voice_call(&self) {
|
||||||
self.send(Data::CloseVoiceCall);
|
self.send(Data::CloseVoiceCall);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn show_relay_hint(
|
|
||||||
&mut self,
|
|
||||||
last_recv_time: tokio::time::Instant,
|
|
||||||
msgtype: &str,
|
|
||||||
title: &str,
|
|
||||||
text: &str,
|
|
||||||
) -> bool {
|
|
||||||
let duration = Duration::from_secs(3);
|
|
||||||
let counter_interval = 3;
|
|
||||||
let lock = self.lc.read().unwrap();
|
|
||||||
let success_time = lock.success_time;
|
|
||||||
let direct = lock.direct.unwrap_or(false);
|
|
||||||
let received = lock.received;
|
|
||||||
drop(lock);
|
|
||||||
if let Some(success_time) = success_time {
|
|
||||||
if direct && last_recv_time.duration_since(success_time) < duration {
|
|
||||||
let retry_for_relay = direct && !received;
|
|
||||||
let retry = check_if_retry(msgtype, title, text, retry_for_relay);
|
|
||||||
if retry && !retry_for_relay {
|
|
||||||
self.lc.write().unwrap().direct_error_counter += 1;
|
|
||||||
if self.lc.read().unwrap().direct_error_counter % counter_interval == 0 {
|
|
||||||
#[cfg(feature = "flutter")]
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
self.lc.write().unwrap().direct_error_counter = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
false
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait InvokeUiSession: Send + Sync + Clone + 'static + Sized + Default {
|
pub trait InvokeUiSession: Send + Sync + Clone + 'static + Sized + Default {
|
||||||
@ -1059,9 +1021,9 @@ impl<T: InvokeUiSession> Interface for Session<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn msgbox(&self, msgtype: &str, title: &str, text: &str, link: &str) {
|
fn msgbox(&self, msgtype: &str, title: &str, text: &str, link: &str) {
|
||||||
let direct = self.lc.read().unwrap().direct.unwrap_or_default();
|
let direct = self.lc.read().unwrap().direct;
|
||||||
let received = self.lc.read().unwrap().received;
|
let received = self.lc.read().unwrap().received;
|
||||||
let retry_for_relay = direct && !received;
|
let retry_for_relay = direct == Some(true) && !received;
|
||||||
let retry = check_if_retry(msgtype, title, text, retry_for_relay);
|
let retry = check_if_retry(msgtype, title, text, retry_for_relay);
|
||||||
self.ui_handler.msgbox(msgtype, title, text, link, retry);
|
self.ui_handler.msgbox(msgtype, title, text, link, retry);
|
||||||
}
|
}
|
||||||
@ -1118,7 +1080,6 @@ impl<T: InvokeUiSession> Interface for Session<T> {
|
|||||||
"Connected, waiting for image...",
|
"Connected, waiting for image...",
|
||||||
"",
|
"",
|
||||||
);
|
);
|
||||||
self.lc.write().unwrap().success_time = Some(tokio::time::Instant::now());
|
|
||||||
}
|
}
|
||||||
self.on_connected(self.lc.read().unwrap().conn_type);
|
self.on_connected(self.lc.read().unwrap().conn_type);
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
|
Loading…
x
Reference in New Issue
Block a user