Create main screen with placeholder networks
This commit is contained in:
parent
f7588296b8
commit
45f8f135c4
8 changed files with 506 additions and 10 deletions
|
|
@ -7,7 +7,7 @@ const RECONNECT_POLL_TIME: Duration = Duration::from_secs(5);
|
||||||
pub struct App {
|
pub struct App {
|
||||||
daemon_client: Arc<Mutex<Option<Channel>>>,
|
daemon_client: Arc<Mutex<Option<Channel>>>,
|
||||||
settings_screen: Controller<settings_screen::SettingsScreen>,
|
settings_screen: Controller<settings_screen::SettingsScreen>,
|
||||||
switch_screen: AsyncController<switch_screen::SwitchScreen>,
|
main_screen: AsyncController<main_screen::MainScreen>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
|
@ -61,8 +61,8 @@ impl AsyncComponent for App {
|
||||||
// TODO: RPC REFACTOR (Handle Error)
|
// TODO: RPC REFACTOR (Handle Error)
|
||||||
let daemon_client = Arc::new(Mutex::new(daemon::daemon_connect().await.ok()));
|
let daemon_client = Arc::new(Mutex::new(daemon::daemon_connect().await.ok()));
|
||||||
|
|
||||||
let switch_screen = switch_screen::SwitchScreen::builder()
|
let main_screen = main_screen::MainScreen::builder()
|
||||||
.launch(switch_screen::SwitchScreenInit {
|
.launch(main_screen::MainScreenInit {
|
||||||
daemon_client: Arc::clone(&daemon_client),
|
daemon_client: Arc::clone(&daemon_client),
|
||||||
})
|
})
|
||||||
.forward(sender.input_sender(), |_| AppMsg::None);
|
.forward(sender.input_sender(), |_| AppMsg::None);
|
||||||
|
|
@ -76,7 +76,7 @@ impl AsyncComponent for App {
|
||||||
let widgets = view_output!();
|
let widgets = view_output!();
|
||||||
|
|
||||||
let view_stack = adw::ViewStack::new();
|
let view_stack = adw::ViewStack::new();
|
||||||
view_stack.add_titled(switch_screen.widget(), None, "Switch");
|
view_stack.add_titled(main_screen.widget(), None, "Burrow");
|
||||||
view_stack.add_titled(settings_screen.widget(), None, "Settings");
|
view_stack.add_titled(settings_screen.widget(), None, "Settings");
|
||||||
|
|
||||||
let view_switcher_bar = adw::ViewSwitcherBar::builder().stack(&view_stack).build();
|
let view_switcher_bar = adw::ViewSwitcherBar::builder().stack(&view_stack).build();
|
||||||
|
|
@ -109,7 +109,7 @@ impl AsyncComponent for App {
|
||||||
|
|
||||||
let model = App {
|
let model = App {
|
||||||
daemon_client,
|
daemon_client,
|
||||||
switch_screen,
|
main_screen,
|
||||||
settings_screen,
|
settings_screen,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -132,8 +132,8 @@ impl AsyncComponent for App {
|
||||||
let mut client = tunnel_client::TunnelClient::new(daemon_client);
|
let mut client = tunnel_client::TunnelClient::new(daemon_client);
|
||||||
if let Err(_e) = client.tunnel_status(burrow_rpc::Empty {}).await {
|
if let Err(_e) = client.tunnel_status(burrow_rpc::Empty {}).await {
|
||||||
disconnected_daemon_client = true;
|
disconnected_daemon_client = true;
|
||||||
self.switch_screen
|
self.main_screen
|
||||||
.emit(switch_screen::SwitchScreenMsg::DaemonDisconnect);
|
.emit(main_screen::MainScreenMsg::DaemonDisconnect);
|
||||||
self.settings_screen
|
self.settings_screen
|
||||||
.emit(settings_screen::SettingsScreenMsg::DaemonStateChange)
|
.emit(settings_screen::SettingsScreenMsg::DaemonStateChange)
|
||||||
}
|
}
|
||||||
|
|
@ -143,8 +143,8 @@ impl AsyncComponent for App {
|
||||||
match daemon::daemon_connect().await {
|
match daemon::daemon_connect().await {
|
||||||
Ok(new_daemon_client) => {
|
Ok(new_daemon_client) => {
|
||||||
*daemon_client = Some(new_daemon_client);
|
*daemon_client = Some(new_daemon_client);
|
||||||
self.switch_screen
|
self.main_screen
|
||||||
.emit(switch_screen::SwitchScreenMsg::DaemonReconnect);
|
.emit(main_screen::MainScreenMsg::DaemonReconnect);
|
||||||
self.settings_screen
|
self.settings_screen
|
||||||
.emit(settings_screen::SettingsScreenMsg::DaemonStateChange)
|
.emit(settings_screen::SettingsScreenMsg::DaemonStateChange)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
9
burrow-gtk/src/components/main/mod.rs
Normal file
9
burrow-gtk/src/components/main/mod.rs
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
mod network_card;
|
||||||
|
mod networks;
|
||||||
|
mod switch;
|
||||||
|
|
||||||
|
pub use network_card::{NetworkCard, NetworkCardInit};
|
||||||
|
pub use networks::{Networks, NetworksInit};
|
||||||
|
pub use switch::{Switch, SwitchInit, SwitchMsg};
|
||||||
49
burrow-gtk/src/components/main/network_card.rs
Normal file
49
burrow-gtk/src/components/main/network_card.rs
Normal file
|
|
@ -0,0 +1,49 @@
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
pub struct NetworkCard {}
|
||||||
|
|
||||||
|
pub struct NetworkCardInit {
|
||||||
|
pub name: String,
|
||||||
|
pub enabled: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum NetworkCardMsg {}
|
||||||
|
|
||||||
|
#[relm4::component(pub, async)]
|
||||||
|
impl AsyncComponent for NetworkCard {
|
||||||
|
type Init = NetworkCardInit;
|
||||||
|
type Input = NetworkCardMsg;
|
||||||
|
type Output = ();
|
||||||
|
type CommandOutput = ();
|
||||||
|
|
||||||
|
view! {
|
||||||
|
gtk::ListBoxRow {
|
||||||
|
set_hexpand: true,
|
||||||
|
set_halign: Align::Center,
|
||||||
|
gtk::Box {
|
||||||
|
gtk::Label {
|
||||||
|
set_label: &init.name
|
||||||
|
},
|
||||||
|
gtk::Switch {
|
||||||
|
set_halign: Align::Center,
|
||||||
|
set_hexpand: false,
|
||||||
|
set_vexpand: false,
|
||||||
|
set_state: init.enabled,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn init(
|
||||||
|
init: Self::Init,
|
||||||
|
root: Self::Root,
|
||||||
|
sender: AsyncComponentSender<Self>,
|
||||||
|
) -> AsyncComponentParts<Self> {
|
||||||
|
let widgets = view_output!();
|
||||||
|
|
||||||
|
let model = NetworkCard {};
|
||||||
|
|
||||||
|
AsyncComponentParts { model, widgets }
|
||||||
|
}
|
||||||
|
}
|
||||||
83
burrow-gtk/src/components/main/networks.rs
Normal file
83
burrow-gtk/src/components/main/networks.rs
Normal file
|
|
@ -0,0 +1,83 @@
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
pub struct Networks {
|
||||||
|
daemon_client: Arc<Mutex<Option<Channel>>>,
|
||||||
|
network_widgets: Vec<AsyncController<NetworkCard>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct NetworksInit {
|
||||||
|
pub daemon_client: Arc<Mutex<Option<Channel>>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum NetworksMsg {
|
||||||
|
None,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[relm4::component(pub, async)]
|
||||||
|
impl AsyncComponent for Networks {
|
||||||
|
type Init = NetworksInit;
|
||||||
|
type Input = NetworksMsg;
|
||||||
|
type Output = ();
|
||||||
|
type CommandOutput = ();
|
||||||
|
|
||||||
|
view! {
|
||||||
|
gtk::Box {
|
||||||
|
set_orientation: gtk::Orientation::Vertical,
|
||||||
|
set_spacing: 5,
|
||||||
|
set_margin_all: 5,
|
||||||
|
set_valign: Align::Start,
|
||||||
|
|
||||||
|
#[name = "networks"]
|
||||||
|
gtk::ListBox {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn init(
|
||||||
|
init: Self::Init,
|
||||||
|
root: Self::Root,
|
||||||
|
sender: AsyncComponentSender<Self>,
|
||||||
|
) -> AsyncComponentParts<Self> {
|
||||||
|
let widgets = view_output!();
|
||||||
|
|
||||||
|
let network_widgets = vec![
|
||||||
|
NetworkCard::builder()
|
||||||
|
.launch(NetworkCardInit {
|
||||||
|
name: "Hello".to_owned(),
|
||||||
|
enabled: true,
|
||||||
|
})
|
||||||
|
.forward(sender.input_sender(), |_| NetworksMsg::None),
|
||||||
|
NetworkCard::builder()
|
||||||
|
.launch(NetworkCardInit {
|
||||||
|
name: "World".to_owned(),
|
||||||
|
enabled: false,
|
||||||
|
})
|
||||||
|
.forward(sender.input_sender(), |_| NetworksMsg::None),
|
||||||
|
NetworkCard::builder()
|
||||||
|
.launch(NetworkCardInit {
|
||||||
|
name: "Yay".to_owned(),
|
||||||
|
enabled: false,
|
||||||
|
})
|
||||||
|
.forward(sender.input_sender(), |_| NetworksMsg::None),
|
||||||
|
];
|
||||||
|
|
||||||
|
widgets.networks.append(network_widgets[0].widget());
|
||||||
|
widgets.networks.append(network_widgets[1].widget());
|
||||||
|
widgets.networks.append(network_widgets[2].widget());
|
||||||
|
|
||||||
|
let model = Networks {
|
||||||
|
daemon_client: init.daemon_client,
|
||||||
|
network_widgets,
|
||||||
|
};
|
||||||
|
|
||||||
|
AsyncComponentParts { model, widgets }
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn update(
|
||||||
|
&mut self,
|
||||||
|
msg: Self::Input,
|
||||||
|
_: AsyncComponentSender<Self>,
|
||||||
|
_root: &Self::Root,
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
}
|
||||||
205
burrow-gtk/src/components/main/switch.rs
Normal file
205
burrow-gtk/src/components/main/switch.rs
Normal file
|
|
@ -0,0 +1,205 @@
|
||||||
|
use super::*;
|
||||||
|
use std::time::Duration;
|
||||||
|
|
||||||
|
const RECONNECT_POLL_TIME: Duration = Duration::from_secs(3);
|
||||||
|
|
||||||
|
pub struct Switch {
|
||||||
|
daemon_client: Arc<Mutex<Option<Channel>>>,
|
||||||
|
switch: gtk::Switch,
|
||||||
|
switch_screen: gtk::Box,
|
||||||
|
disconnected_banner: adw::Banner,
|
||||||
|
|
||||||
|
_tunnel_state_worker: WorkerController<AsyncTunnelStateHandler>,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct SwitchInit {
|
||||||
|
pub daemon_client: Arc<Mutex<Option<Channel>>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Eq)]
|
||||||
|
pub enum SwitchMsg {
|
||||||
|
None,
|
||||||
|
DaemonReconnect,
|
||||||
|
DaemonDisconnect,
|
||||||
|
Start,
|
||||||
|
Stop,
|
||||||
|
SwitchSetStart,
|
||||||
|
SwitchSetStop,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[relm4::component(pub, async)]
|
||||||
|
impl AsyncComponent for Switch {
|
||||||
|
type Init = SwitchInit;
|
||||||
|
type Input = SwitchMsg;
|
||||||
|
type Output = ();
|
||||||
|
type CommandOutput = ();
|
||||||
|
|
||||||
|
view! {
|
||||||
|
gtk::Box {
|
||||||
|
set_orientation: gtk::Orientation::Vertical,
|
||||||
|
set_valign: Align::Fill,
|
||||||
|
|
||||||
|
gtk::Box {
|
||||||
|
set_orientation: gtk::Orientation::Vertical,
|
||||||
|
set_spacing: 5,
|
||||||
|
set_margin_all: 5,
|
||||||
|
set_valign: Align::Start,
|
||||||
|
|
||||||
|
#[name(setup_banner)]
|
||||||
|
adw::Banner {
|
||||||
|
set_title: "Burrow is not running!",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
#[name(switch_screen)]
|
||||||
|
gtk::Box {
|
||||||
|
set_orientation: gtk::Orientation::Vertical,
|
||||||
|
set_spacing: 10,
|
||||||
|
set_margin_all: 5,
|
||||||
|
set_valign: Align::Center,
|
||||||
|
set_vexpand: true,
|
||||||
|
|
||||||
|
gtk::Label {
|
||||||
|
set_label: "Burrow Switch",
|
||||||
|
},
|
||||||
|
|
||||||
|
#[name(switch)]
|
||||||
|
gtk::Switch {
|
||||||
|
set_halign: Align::Center,
|
||||||
|
set_hexpand: false,
|
||||||
|
set_vexpand: false,
|
||||||
|
connect_active_notify => move |switch|
|
||||||
|
switch_sender.input(if switch.is_active() { SwitchMsg::Start } else { SwitchMsg::Stop })
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn init(
|
||||||
|
init: Self::Init,
|
||||||
|
root: Self::Root,
|
||||||
|
sender: AsyncComponentSender<Self>,
|
||||||
|
) -> AsyncComponentParts<Self> {
|
||||||
|
let mut initial_daemon_server_down = false;
|
||||||
|
|
||||||
|
if let Some(daemon_client) = init.daemon_client.lock().await.as_mut() {
|
||||||
|
let mut client = tunnel_client::TunnelClient::new(daemon_client);
|
||||||
|
if client
|
||||||
|
.tunnel_status(burrow_rpc::Empty {})
|
||||||
|
.await
|
||||||
|
.as_mut()
|
||||||
|
.is_err()
|
||||||
|
{
|
||||||
|
initial_daemon_server_down = true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
initial_daemon_server_down = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
let switch_sender = sender.clone();
|
||||||
|
let widgets = view_output!();
|
||||||
|
|
||||||
|
if initial_daemon_server_down {
|
||||||
|
*init.daemon_client.lock().await = None;
|
||||||
|
widgets.switch.set_active(false);
|
||||||
|
widgets.switch_screen.set_sensitive(false);
|
||||||
|
widgets.setup_banner.set_revealed(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
let model = Switch {
|
||||||
|
daemon_client: init.daemon_client,
|
||||||
|
switch: widgets.switch.clone(),
|
||||||
|
switch_screen: widgets.switch_screen.clone(),
|
||||||
|
disconnected_banner: widgets.setup_banner.clone(),
|
||||||
|
_tunnel_state_worker: AsyncTunnelStateHandler::builder()
|
||||||
|
.detach_worker(())
|
||||||
|
.forward(sender.input_sender(), |_| SwitchMsg::None),
|
||||||
|
};
|
||||||
|
|
||||||
|
widgets.switch.set_active(false);
|
||||||
|
|
||||||
|
AsyncComponentParts { model, widgets }
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn update(
|
||||||
|
&mut self,
|
||||||
|
msg: Self::Input,
|
||||||
|
_: AsyncComponentSender<Self>,
|
||||||
|
_root: &Self::Root,
|
||||||
|
) {
|
||||||
|
let mut disconnected_daemon_client = false;
|
||||||
|
|
||||||
|
if let Some(daemon_client) = self.daemon_client.lock().await.as_mut() {
|
||||||
|
let mut client = tunnel_client::TunnelClient::new(daemon_client);
|
||||||
|
match msg {
|
||||||
|
Self::Input::Start => {
|
||||||
|
if let Err(_e) = client.tunnel_start(burrow_rpc::Empty {}).await {
|
||||||
|
disconnected_daemon_client = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Self::Input::Stop => {
|
||||||
|
if let Err(_e) = client.tunnel_stop(burrow_rpc::Empty {}).await {
|
||||||
|
disconnected_daemon_client = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Self::Input::SwitchSetStart => {
|
||||||
|
self.switch.set_active(true);
|
||||||
|
}
|
||||||
|
Self::Input::SwitchSetStop => {
|
||||||
|
self.switch.set_active(false);
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
disconnected_daemon_client = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if msg == Self::Input::DaemonReconnect {
|
||||||
|
self.disconnected_banner.set_revealed(false);
|
||||||
|
self.switch_screen.set_sensitive(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
if disconnected_daemon_client || msg == Self::Input::DaemonDisconnect {
|
||||||
|
*self.daemon_client.lock().await = None;
|
||||||
|
self.switch_screen.set_sensitive(false);
|
||||||
|
self.disconnected_banner.set_revealed(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct AsyncTunnelStateHandler;
|
||||||
|
|
||||||
|
impl Worker for AsyncTunnelStateHandler {
|
||||||
|
type Init = ();
|
||||||
|
type Input = ();
|
||||||
|
type Output = SwitchMsg;
|
||||||
|
|
||||||
|
fn init(_: Self::Init, _sender: ComponentSender<Self>) -> Self {
|
||||||
|
Self
|
||||||
|
}
|
||||||
|
|
||||||
|
fn update(&mut self, _: (), sender: ComponentSender<Self>) {
|
||||||
|
let rt = tokio::runtime::Runtime::new().unwrap();
|
||||||
|
let task = rt.spawn(async move {
|
||||||
|
loop {
|
||||||
|
let conn = daemon::daemon_connect().await;
|
||||||
|
if let Ok(conn) = conn {
|
||||||
|
let mut client = tunnel_client::TunnelClient::new(conn);
|
||||||
|
if let Ok(mut res) = client.tunnel_status(burrow_rpc::Empty {}).await {
|
||||||
|
let stream = res.get_mut();
|
||||||
|
while let Ok(Some(msg)) = stream.message().await {
|
||||||
|
sender
|
||||||
|
.output(match msg.state() {
|
||||||
|
burrow_rpc::State::Running => SwitchMsg::SwitchSetStart,
|
||||||
|
burrow_rpc::State::Stopped => SwitchMsg::SwitchSetStop,
|
||||||
|
})
|
||||||
|
.unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
tokio::time::sleep(RECONNECT_POLL_TIME).await;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
rt.block_on(task).unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
109
burrow-gtk/src/components/main_screen.rs
Normal file
109
burrow-gtk/src/components/main_screen.rs
Normal file
|
|
@ -0,0 +1,109 @@
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
pub struct MainScreen {
|
||||||
|
switch: AsyncController<main::Switch>,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct MainScreenInit {
|
||||||
|
pub daemon_client: Arc<Mutex<Option<Channel>>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum MainScreenMsg {
|
||||||
|
None,
|
||||||
|
DaemonDisconnect,
|
||||||
|
DaemonReconnect,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[relm4::component(pub, async)]
|
||||||
|
impl AsyncComponent for MainScreen {
|
||||||
|
type Init = MainScreenInit;
|
||||||
|
type Input = MainScreenMsg;
|
||||||
|
type Output = ();
|
||||||
|
type CommandOutput = ();
|
||||||
|
|
||||||
|
view! {
|
||||||
|
gtk::Box {
|
||||||
|
set_orientation: gtk::Orientation::Vertical,
|
||||||
|
set_valign: Align::Fill,
|
||||||
|
set_valign: Align::Center,
|
||||||
|
|
||||||
|
// gtk::Box {
|
||||||
|
// set_orientation: gtk::Orientation::Vertical,
|
||||||
|
// set_spacing: 5,
|
||||||
|
// set_margin_all: 5,
|
||||||
|
// set_valign: Align::Start,
|
||||||
|
|
||||||
|
// #[name(setup_banner)]
|
||||||
|
// adw::Banner {
|
||||||
|
// set_title: "Burrow is not running!",
|
||||||
|
// },
|
||||||
|
// },
|
||||||
|
|
||||||
|
gtk::Box {
|
||||||
|
set_orientation: gtk::Orientation::Vertical,
|
||||||
|
set_spacing: 10,
|
||||||
|
set_margin_all: 5,
|
||||||
|
set_valign: Align::Center,
|
||||||
|
set_vexpand: true,
|
||||||
|
},
|
||||||
|
|
||||||
|
#[name(content)]
|
||||||
|
gtk::Box {
|
||||||
|
set_orientation: gtk::Orientation::Vertical,
|
||||||
|
set_spacing: 10,
|
||||||
|
set_margin_all: 5,
|
||||||
|
set_valign: Align::Center,
|
||||||
|
set_vexpand: true,
|
||||||
|
|
||||||
|
gtk::Label {
|
||||||
|
set_label: "Main Screen",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn init(
|
||||||
|
init: Self::Init,
|
||||||
|
root: Self::Root,
|
||||||
|
sender: AsyncComponentSender<Self>,
|
||||||
|
) -> AsyncComponentParts<Self> {
|
||||||
|
let switch = main::Switch::builder()
|
||||||
|
.launch(main::SwitchInit {
|
||||||
|
daemon_client: Arc::clone(&init.daemon_client),
|
||||||
|
})
|
||||||
|
.forward(sender.input_sender(), |_| MainScreenMsg::None);
|
||||||
|
|
||||||
|
let networks = main::Networks::builder()
|
||||||
|
.launch(main::NetworksInit {
|
||||||
|
daemon_client: Arc::clone(&init.daemon_client),
|
||||||
|
})
|
||||||
|
.forward(sender.input_sender(), |_| MainScreenMsg::None);
|
||||||
|
|
||||||
|
let widgets = view_output!();
|
||||||
|
|
||||||
|
widgets.content.append(networks.widget());
|
||||||
|
widgets.content.append(switch.widget());
|
||||||
|
|
||||||
|
let model = MainScreen { switch };
|
||||||
|
|
||||||
|
AsyncComponentParts { model, widgets }
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn update(
|
||||||
|
&mut self,
|
||||||
|
msg: Self::Input,
|
||||||
|
_: AsyncComponentSender<Self>,
|
||||||
|
_root: &Self::Root,
|
||||||
|
) {
|
||||||
|
match msg {
|
||||||
|
MainScreenMsg::DaemonDisconnect => {
|
||||||
|
self.switch.emit(main::SwitchMsg::DaemonDisconnect);
|
||||||
|
}
|
||||||
|
MainScreenMsg::DaemonReconnect => {
|
||||||
|
self.switch.emit(main::SwitchMsg::DaemonReconnect);
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -19,9 +19,11 @@ use burrow_rpc::tunnel_client;
|
||||||
use tonic::transport::Channel;
|
use tonic::transport::Channel;
|
||||||
|
|
||||||
mod app;
|
mod app;
|
||||||
|
mod main;
|
||||||
|
mod main_screen;
|
||||||
mod settings;
|
mod settings;
|
||||||
mod settings_screen;
|
mod settings_screen;
|
||||||
mod switch_screen;
|
// mod switch_screen;
|
||||||
|
|
||||||
pub use app::*;
|
pub use app::*;
|
||||||
pub use settings::{DaemonGroupMsg, DiagGroupMsg};
|
pub use settings::{DaemonGroupMsg, DiagGroupMsg};
|
||||||
|
|
|
||||||
39
burrow-gtk/src/components/template.rs
Normal file
39
burrow-gtk/src/components/template.rs
Normal file
|
|
@ -0,0 +1,39 @@
|
||||||
|
pub struct Template {}
|
||||||
|
|
||||||
|
pub struct TemplateInit {}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum TemplateMsg {}
|
||||||
|
|
||||||
|
#[relm4::component(pub, async)]
|
||||||
|
impl AsyncComponent for Template {
|
||||||
|
type Init = TemplateInit;
|
||||||
|
type Input = TemplateMsg;
|
||||||
|
type Output = ();
|
||||||
|
type CommandOutput = ();
|
||||||
|
|
||||||
|
view! {
|
||||||
|
gtk::Box {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn init(
|
||||||
|
init: Self::Init,
|
||||||
|
root: Self::Root,
|
||||||
|
sender: AsyncComponentSender<Self>,
|
||||||
|
) -> AsyncComponentParts<Self> {
|
||||||
|
let widgets = view_output!();
|
||||||
|
|
||||||
|
let model = Template {};
|
||||||
|
|
||||||
|
AsyncComponentParts { model, widgets }
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn update(
|
||||||
|
&mut self,
|
||||||
|
msg: Self::Input,
|
||||||
|
_: AsyncComponentSender<Self>,
|
||||||
|
_root: &Self::Root,
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue