ReSet/src/components/wifi/wifiEntry.rs

208 lines
7.7 KiB
Rust

use crate::components::base::popup::{self, Popup};
use crate::components::wifi::wifiEntryImpl;
use adw::glib;
use adw::glib::{Object, PropertySet};
use adw::prelude::{ButtonExt, EditableExt, EntryExt, PopoverExt};
use adw::subclass::prelude::ObjectSubclassIsExt;
use dbus::blocking::Connection;
use dbus::Error;
use glib::{clone, Cast};
use gtk::prelude::WidgetExt;
use gtk::{AlertDialog, Editable, GestureClick, PasswordEntry, PasswordEntryBuffer, Window};
use std::sync::atomic::AtomicBool;
use std::sync::Arc;
use std::time::Duration;
use ReSet_Lib::network::network::{AccessPoint, WifiStrength};
glib::wrapper! {
pub struct WifiEntry(ObjectSubclass<wifiEntryImpl::WifiEntry>)
@extends gtk::Box, gtk::Widget,
@implements gtk::Accessible, gtk::Buildable, gtk::Actionable, gtk::ConstraintTarget;
}
unsafe impl Send for WifiEntry {}
unsafe impl Sync for WifiEntry {}
impl WifiEntry {
pub fn new(access_point: AccessPoint) -> Arc<Self> {
let entry: Arc<WifiEntry> = Arc::new(Object::builder().build());
let stored_entry = entry.clone();
let new_entry = entry.clone();
let entryImp = entry.imp();
let strength = WifiStrength::from_u8(access_point.strength);
let ssid = access_point.ssid.clone();
let name_opt = String::from_utf8(ssid).unwrap_or_else(|_| String::from(""));
let name = name_opt.as_str();
let stored = access_point.stored;
entryImp.wifiStrength.set(strength);
entryImp.resetWifiLabel.get().set_text(name);
entryImp.resetWifiEncrypted.set_visible(false);
// TODO handle encryption thing
entryImp
.resetWifiStrength
.get()
.set_from_icon_name(match strength {
WifiStrength::Excellent => Some("network-wireless-signal-excellent-symbolic"),
WifiStrength::Ok => Some("network-wireless-signal-ok-symbolic"),
WifiStrength::Weak => Some("network-wireless-signal-weak-symbolic"),
WifiStrength::None => Some("network-wireless-signal-none-symbolic"),
});
if access_point.connected == true {
entryImp
.resetWifiConnected
.get()
.set_from_icon_name(Some("network-wireless-connected-symbolic"));
}
{
let mut wifiName = entryImp.wifiName.borrow_mut();
*wifiName = String::from(name);
}
entryImp.accessPoint.set(access_point);
let gesture = GestureClick::new();
if stored {
entryImp
.resetWifiStored
.get()
.set_from_icon_name(Some("document-save-symbolic"));
gesture.connect_released(move |_, _, _, _| {
click_stored_network(stored_entry.clone());
});
} else {
gesture.connect_released(move |_, _, _, _| {
click_new_network(new_entry.clone());
});
}
entry.add_controller(gesture);
entry
}
}
pub fn click_stored_network(entry: Arc<WifiEntry>) {
let alert = AlertDialog::builder().build();
let root = &entry.root().unwrap();
let root = root.downcast_ref::<gtk::Window>();
if root.is_none() {
println!("ERROR BRO");
return;
}
let root = root.unwrap();
// TODO handle unknown access point -> should be done by having 2 different categories
let entryImp = entry.imp();
let conn = Connection::new_session().unwrap();
let proxy = conn.with_proxy(
"org.xetibo.ReSet",
"/org/xetibo/ReSet",
Duration::from_millis(1000),
);
let access_point = entryImp.accessPoint.clone().into_inner();
if access_point.connected == true {
let res: Result<(bool,), Error> =
proxy.method_call("org.xetibo.ReSet", "DisconnectFromCurrentAccessPoint", ());
if res.is_err() {
alert.set_message("Error on connecting to dbus.");
alert.show(Some(root));
return;
}
let (res,) = res.unwrap();
if res == false {
alert.set_message("Could not disconnect from access point.");
alert.show(Some(root));
} else {
entryImp.resetWifiConnected.get().set_from_icon_name(None);
let mut access_point = entryImp.accessPoint.borrow_mut();
(*access_point).connected = false;
}
return;
}
dbg!(access_point.clone());
let res: Result<(bool,), Error> = proxy.method_call(
"org.xetibo.ReSet",
"ConnectToKnownAccessPoint",
(access_point,),
);
if res.is_err() {
alert.set_message("Error on connecting to dbus.");
alert.show(Some(root));
} else {
let (res,) = res.unwrap();
if res == false {
alert.set_message("Could not connect to access point.");
alert.show(Some(root));
} else {
entryImp
.resetWifiConnected
.get()
.set_from_icon_name(Some("network-wireless-connected-symbolic"));
let mut access_point = entryImp.accessPoint.borrow_mut();
(*access_point).connected = true;
}
}
}
pub fn click_new_network(entry: Arc<WifiEntry>) {
let connect_new_network =
|entry: Arc<WifiEntry>, access_point: AccessPoint, password: String| -> bool {
let alert = AlertDialog::builder().build();
let root = &entry.root().unwrap();
let root = root.downcast_ref::<gtk::Window>();
if root.is_none() {
println!("ERROR BRO");
return false;
}
let root = root.unwrap();
let conn = Connection::new_session().unwrap();
let proxy = conn.with_proxy(
"org.xetibo.ReSet",
"/org/xetibo/ReSet",
Duration::from_millis(10000),
);
// TODO crate spinner animation and block UI
let res: Result<(bool,), Error> = proxy.method_call(
"org.xetibo.ReSet",
"ConnectToNewAccessPoint",
(access_point, password),
);
if res.is_err() {
alert.set_message("Could not connect to dbus.");
alert.show(Some(root));
return false;
}
if res.unwrap() == (false,) {
alert.set_message("Could not connect to access point.");
alert.show(Some(root));
return false;
}
true
};
let result = Arc::new(AtomicBool::new(false));
let result_ref = result.clone();
let result_ref_button = result.clone();
let entryImp = entry.imp();
let popupImp = entryImp.resetWifiPopup.imp();
popupImp
.resetPopupEntry
.connect_activate(clone!(@weak entry as origEntry, @weak entryImp => move |entry| {
result_ref.store(
connect_new_network(origEntry, entryImp.accessPoint.clone().take(), entry.text().to_string()),
std::sync::atomic::Ordering::SeqCst,
);
entryImp.resetWifiPopup.popdown();
}));
popupImp
.resetPopupButton
.connect_clicked(clone!(@weak entry as origEntry,@weak entryImp, @weak popupImp => move |_| {
let entry = entryImp.resetWifiPopup.imp().resetPopupEntry.text().to_string();
result_ref_button.store(
connect_new_network(origEntry, entryImp.accessPoint.clone().take(), entry),
std::sync::atomic::Ordering::SeqCst,
);
entryImp.resetWifiPopup.popdown();
}));
entryImp.resetWifiPopup.popup();
println!(
"result is {}",
result.load(std::sync::atomic::Ordering::SeqCst)
);
}