login: Show network state

This only disables navigation when no network is available, since the
homeserver may be on a local network.
This commit is contained in:
Julian Sparber 2022-07-25 23:44:41 +02:00
parent 8a6a209f54
commit 44c96d3d4c
5 changed files with 133 additions and 6 deletions

View file

@ -29,7 +29,7 @@
<object class="GtkBox">
<property name="orientation">vertical</property>
<child>
<object class="GtkInfoBar">
<object class="GtkInfoBar" id="development_info_bar">
<property name="message-type">warning</property>
<child>
<object class="AdwClamp">
@ -47,6 +47,24 @@
</child>
</object>
</child>
<child>
<object class="GtkInfoBar" id="offline_info_bar">
<property name="message-type">warning</property>
<child>
<object class="AdwClamp">
<property name="maximum-size">440</property>
<property name="tightening-threshold">340</property>
<property name="hexpand">true</property>
<child>
<object class="GtkLabel" id="offline_info_bar_label">
<property name="justify">center</property>
<property name="wrap">True</property>
</object>
</child>
</object>
</child>
</object>
</child>
<child>
<object class="AdwClamp">
<property name="maximum-size">440</property>
@ -136,3 +154,4 @@
</child>
</template>
</interface>

View file

@ -28,6 +28,24 @@
</child>
</object>
</child>
<child>
<object class="GtkInfoBar" id="offline_info_bar">
<property name="message-type">warning</property>
<child>
<object class="AdwClamp">
<property name="maximum-size">440</property>
<property name="tightening-threshold">340</property>
<property name="hexpand">true</property>
<child>
<object class="GtkLabel" id="offline_info_bar_label">
<property name="justify">center</property>
<property name="wrap">True</property>
</object>
</child>
</object>
</child>
</object>
</child>
<child>
<object class="GtkStack" id="main_stack">
<property name="transition-type">crossfade</property>
@ -229,3 +247,4 @@
</child>
</template>
</interface>

View file

@ -45,6 +45,7 @@ src/components/editable_avatar.rs
src/components/location_viewer.rs
src/components/media_content_viewer.rs
src/error_page.rs
src/greeter.rs
src/login/mod.rs
src/secret.rs
src/session/account_settings/devices_page/device_list.rs

View file

@ -1,5 +1,7 @@
use adw::subclass::prelude::BinImpl;
use gtk::{self, glib, prelude::*, subclass::prelude::*, CompositeTemplate};
use gtk::{self, gio, glib, glib::clone, prelude::*, subclass::prelude::*, CompositeTemplate};
use crate::gettext;
mod imp {
use glib::subclass::InitializingObject;
@ -13,6 +15,12 @@ mod imp {
pub back_button: TemplateChild<gtk::Button>,
#[template_child]
pub login_button: TemplateChild<gtk::Button>,
#[template_child]
pub development_info_bar: TemplateChild<gtk::InfoBar>,
#[template_child]
pub offline_info_bar: TemplateChild<gtk::InfoBar>,
#[template_child]
pub offline_info_bar_label: TemplateChild<gtk::Label>,
}
#[glib::object_subclass]
@ -31,7 +39,18 @@ mod imp {
}
}
impl ObjectImpl for Greeter {}
impl ObjectImpl for Greeter {
fn constructed(&self, obj: &Self::Type) {
self.parent_constructed(obj);
let monitor = gio::NetworkMonitor::default();
monitor.connect_network_changed(clone!(@weak obj => move |_, _| {
obj.update_network_state();
}));
obj.update_network_state();
}
}
impl WidgetImpl for Greeter {}
@ -51,6 +70,28 @@ impl Greeter {
pub fn default_widget(&self) -> gtk::Widget {
self.imp().login_button.get().upcast()
}
fn update_network_state(&self) {
let priv_ = self.imp();
let monitor = gio::NetworkMonitor::default();
if !monitor.is_network_available() {
priv_.development_info_bar.set_revealed(false);
priv_
.offline_info_bar_label
.set_label(&gettext("No network connection"));
priv_.offline_info_bar.set_revealed(true);
} else if monitor.connectivity() < gio::NetworkConnectivity::Full {
priv_.development_info_bar.set_revealed(false);
priv_
.offline_info_bar_label
.set_label(&gettext("No Internet connection"));
priv_.offline_info_bar.set_revealed(true);
} else {
priv_.development_info_bar.set_revealed(true);
priv_.offline_info_bar.set_revealed(false);
}
}
}
impl Default for Greeter {

View file

@ -1,6 +1,6 @@
use adw::{prelude::*, subclass::prelude::BinImpl};
use gettextrs::gettext;
use gtk::{self, glib, glib::clone, subclass::prelude::*, CompositeTemplate};
use gtk::{self, gio, glib, glib::clone, subclass::prelude::*, CompositeTemplate};
use log::{debug, warn};
use matrix_sdk::{
config::RequestConfig,
@ -63,6 +63,10 @@ mod imp {
pub sso_box: TemplateChild<gtk::Box>,
#[template_child]
pub more_sso_option: TemplateChild<gtk::Button>,
#[template_child]
pub offline_info_bar: TemplateChild<gtk::InfoBar>,
#[template_child]
pub offline_info_bar_label: TemplateChild<gtk::Label>,
pub prepared_source_id: RefCell<Option<SignalHandlerId>>,
pub logged_out_source_id: RefCell<Option<SignalHandlerId>>,
pub ready_source_id: RefCell<Option<SignalHandlerId>>,
@ -159,6 +163,13 @@ mod imp {
self.parent_constructed(obj);
let monitor = gio::NetworkMonitor::default();
monitor.connect_network_changed(clone!(@weak obj => move |_, _| {
obj.update_network_state();
}));
obj.update_network_state();
self.main_stack
.connect_visible_child_notify(clone!(@weak obj => move |_|
obj.update_next_action();
@ -279,13 +290,21 @@ impl Login {
} else {
build_homeserver_url(homeserver.as_str()).is_ok()
};
self.action_set_enabled("login.next", enabled);
self.action_set_enabled(
"login.next",
enabled && gio::NetworkMonitor::default().is_network_available(),
);
priv_.next_button.set_visible(true);
}
"password" => {
let username_length = priv_.username_entry.text().len();
let password_length = priv_.password_entry.text().len();
self.action_set_enabled("login.next", username_length != 0 && password_length != 0);
self.action_set_enabled(
"login.next",
username_length != 0
&& password_length != 0
&& gio::NetworkMonitor::default().is_network_available(),
);
priv_.next_button.set_visible(true);
}
_ => {
@ -633,6 +652,34 @@ impl Login {
.and_then(|root| root.downcast().ok())
.expect("Login needs to have a parent window")
}
fn update_network_state(&self) {
let priv_ = self.imp();
let monitor = gio::NetworkMonitor::default();
if !monitor.is_network_available() {
priv_
.offline_info_bar_label
.set_label(&gettext("No network connection"));
priv_.offline_info_bar.set_revealed(true);
self.update_next_action();
priv_.sso_box.set_sensitive(false);
priv_.more_sso_option.set_sensitive(false);
} else if monitor.connectivity() < gio::NetworkConnectivity::Full {
priv_
.offline_info_bar_label
.set_label(&gettext("No Internet connection"));
priv_.offline_info_bar.set_revealed(true);
self.update_next_action();
priv_.sso_box.set_sensitive(true);
priv_.more_sso_option.set_sensitive(true);
} else {
priv_.offline_info_bar.set_revealed(false);
self.update_next_action();
priv_.sso_box.set_sensitive(true);
priv_.more_sso_option.set_sensitive(true);
}
}
}
impl Default for Login {