diff --git a/src/scheduler.rs b/src/scheduler.rs index 49de54e3f..09ebe0444 100644 --- a/src/scheduler.rs +++ b/src/scheduler.rs @@ -48,7 +48,7 @@ impl Context { pub async fn maybe_network_lost(&self) { let lock = self.scheduler.read().await; lock.maybe_network_lost().await; - connectivity::idle_interrupted(lock).await; + connectivity::maybe_network_lost(self, lock).await; } pub(crate) async fn interrupt_inbox(&self, info: InterruptInfo) { diff --git a/src/scheduler/connectivity.rs b/src/scheduler/connectivity.rs index 701906a39..0f919e03f 100644 --- a/src/scheduler/connectivity.rs +++ b/src/scheduler/connectivity.rs @@ -20,7 +20,7 @@ pub enum Connectivity { // the top) take priority. This means that e.g. if any folder has an error - usually // because there is no internet connection - the connectivity for the whole // account will be `Notconnected`. -#[derive(Debug, Clone, PartialEq, Eq, EnumProperty)] +#[derive(Debug, Clone, PartialEq, Eq, EnumProperty, PartialOrd)] enum DetailedConnectivity { Error(String), Uninitialized, @@ -193,6 +193,43 @@ pub(crate) async fn idle_interrupted(scheduler: RwLockReadGuard<'_, Scheduler>) // of what we do here. } +/// Set the connectivity to "Not connected" after a call to dc_maybe_network_lost(). +/// If we did not do this, the connectivity would stay "Connected" for quite a long time +/// after `maybe_network_lost()` was called. +pub(crate) async fn maybe_network_lost( + context: &Context, + scheduler: RwLockReadGuard<'_, Scheduler>, +) { + let stores = match &*scheduler { + Scheduler::Running { + inbox, + mvbox, + sentbox, + .. + } => [ + inbox.state.connectivity.clone(), + mvbox.state.connectivity.clone(), + sentbox.state.connectivity.clone(), + ], + Scheduler::Stopped => return, + }; + drop(scheduler); + + for store in &stores { + let mut connectivity_lock = store.0.lock().await; + if !matches!( + *connectivity_lock, + DetailedConnectivity::Uninitialized + | DetailedConnectivity::Error(_) + | DetailedConnectivity::NotConfigured, + ) { + *connectivity_lock = DetailedConnectivity::Error("Connection lost".to_string()); + } + drop(connectivity_lock); + } + context.emit_event(EventType::ConnectivityChanged); +} + impl fmt::Debug for ConnectivityStore { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { if let Some(guard) = self.0.try_lock() {