azalea_shell/factory/network/
connection.rs

1use azalea_service::StaticServiceManager;
2use gtk::prelude::*;
3use relm4::{
4    FactorySender,
5    prelude::{DynamicIndex, FactoryComponent},
6};
7use zbus::zvariant::OwnedObjectPath;
8
9use crate::{
10    icon,
11    service::{self, dbus::network_manager::proxy::NetworkManagerSettingsConnectionProxyBlocking},
12};
13
14#[derive(Debug)]
15pub struct Model {
16    settings: OwnedObjectPath,
17    name: String,
18    #[allow(unused)]
19    proxy: Option<NetworkManagerSettingsConnectionProxyBlocking<'static>>,
20    active_connection: Option<OwnedObjectPath>,
21    #[allow(unused)]
22    connection: Option<zbus::blocking::Connection>,
23}
24
25#[derive(Debug)]
26pub enum Input {
27    Toggle,
28    Connect,
29    Disconnect,
30}
31
32#[derive(Debug)]
33pub enum Output {}
34
35#[relm4::factory(pub)]
36impl FactoryComponent for Model {
37    /// `(Settings, Option<ActiveConnection>)`
38    type Init = (OwnedObjectPath, Option<OwnedObjectPath>);
39    type Input = Input;
40    type Output = Output;
41    type CommandOutput = ();
42    type ParentWidget = gtk::Box;
43
44    view! {
45        #[root]
46        gtk::Box {
47            set_spacing: 12,
48
49            gtk::Label {
50                set_halign: gtk::Align::Start,
51                set_hexpand: true,
52                set_label: &self.name,
53            },
54
55            gtk::Button {
56                set_halign: gtk::Align::End,
57
58                #[watch]
59                set_icon_name: if self.active_connection.is_some() {
60                    icon::PLUG_CONNECTED
61                } else {
62                    icon::PLUG_DISCONNECTED
63                },
64
65                #[watch]
66                set_css_classes: if self.active_connection.is_some() {
67                    &[ "azalea-primary-container" ]
68                } else {
69                    &[]
70                },
71
72                connect_clicked => Input::Toggle
73            }
74        }
75    }
76
77    fn init_model(init: Self::Init, _index: &DynamicIndex, _sender: FactorySender<Self>) -> Self {
78        let connection = zbus::blocking::Connection::system().ok();
79
80        let proxy = connection.as_ref().and_then(|conn| {
81            NetworkManagerSettingsConnectionProxyBlocking::new(&conn, init.0.clone()).ok()
82        });
83
84        Self {
85            connection,
86            settings: init.0,
87            name: proxy
88                .as_ref()
89                .and_then(|p| p.get_settings().ok())
90                .and_then(|s| {
91                    s.get("connection")
92                        .and_then(|c| c.get("id"))
93                        .map(|v| v.to_string().replace('"', ""))
94                })
95                .unwrap_or(format!("unknown")),
96            active_connection: init.1,
97            proxy,
98        }
99    }
100
101    fn update(&mut self, message: Self::Input, sender: FactorySender<Self>) {
102        match message {
103            Input::Toggle => {
104                if self.active_connection.is_some() {
105                    self.update(Input::Disconnect, sender);
106                } else {
107                    self.update(Input::Connect, sender);
108                }
109            }
110            Input::Connect => {
111                service::dbus::network_manager::Service::send(
112                    service::dbus::network_manager::Input::ActivateConnection {
113                        connection: Some(self.settings.clone()),
114                        device: None,
115                        specific_object: None,
116                    },
117                );
118            }
119            Input::Disconnect => {
120                if let Some(active_connection) = &self.active_connection {
121                    service::dbus::network_manager::Service::send(
122                        service::dbus::network_manager::Input::DeactivateConnection {
123                            active_connection: active_connection.clone(),
124                        },
125                    );
126                }
127            }
128        }
129    }
130}