More work on Network stage.

This commit is contained in:
2026-04-23 00:44:01 +02:00
parent 01617374a1
commit a83dbc27f2
8 changed files with 396 additions and 176 deletions
+136 -63
View File
@@ -19,24 +19,27 @@
it needed for installation to process.
*/
use toml::Table;
use iced::{Alignment, widget};
use iced::{Alignment, Task, widget};
use iced_moving_picture::widget::apng;
use rust_i18n::t;
use smol;
use std::collections::HashMap;
use toml::Table;
use crate::stage;
use crate::stage::StageResult;
#[derive(Debug, Clone)]
pub enum State {
Init,
Cheking,
ConnOK,
ConnBad,
CheckFailed,
Normal,
}
#[derive(Debug, Clone)]
pub enum CheckResult {
Connected,
NoConnection,
CheckError,
}
#[derive(Debug, Clone)]
@@ -45,103 +48,173 @@ pub struct NetworkStage {
state: State,
use_net_settings: bool,
reqire_network: bool,
spinner_frames: apng::Frames,
}
#[derive(Debug, Clone)]
pub enum Message {
Next,
Back,
StateChange(State),
UseSettingsTogle(bool)
UseSettingsTogle(bool),
CheckNetwork,
CheckCompleted(CheckResult),
}
#[derive(Debug)]
pub enum UpdateResult {
StageAction(stage::StageAction),
Task(Task<Message>),
}
fn check_connection_blocking() -> CheckResult {
use std::process::Command;
match Command::new("nm-online").arg("-q").status() {
Ok(status) => {
if status.success() {
CheckResult::Connected
} else {
CheckResult::NoConnection
}
}
Err(ex) => {
println!("Exception while trying to chen net connectivity: {}", ex);
CheckResult::CheckError
}
}
}
async fn check_connected() -> CheckResult {
use blocking;
let chek_result = blocking::unblock(|| check_connection_blocking()).await;
return chek_result;
}
impl NetworkStage {
pub fn new(toml_config: &Table) -> Self {
let mut reqire_network = false;
if let Some(reqire_network_conf) = toml_config.get("network")
.and_then(|v|v.as_table())
.and_then(|v| v.get("reqire_network"))
.and_then(|v| v.as_bool())
if let Some(reqire_network_conf) = toml_config
.get("network")
.and_then(|v| v.as_table())
.and_then(|v| v.get("reqire_network"))
.and_then(|v| v.as_bool())
{
println!("Config value reqire_network read {}", reqire_network_conf);
reqire_network = reqire_network_conf;
}
else {
} else {
println!("Error parsing network config. Using default values.");
}
let spinner_frames =
apng::Frames::from_bytes(include_bytes!("spiner.apng").to_vec()).unwrap();
Self {
internet_active: false,
state: State::Init,
state: State::Cheking,
use_net_settings: false,
reqire_network: reqire_network
reqire_network: reqire_network,
spinner_frames: spinner_frames,
}
}
fn check_connected(&mut self) -> Result<bool, std::io::Error> {
use std::process::Command;
let status = Command::new("nm-online").arg("-q").status()?;
if status.success() {
self.internet_active = true;
Ok(true)
} else {
self.internet_active = false;
Ok(false)
}
}
fn gen_result(&self) -> StageResult {
StageResult {
name: "network".into(),
config: Some(HashMap::from([(
"accepted".to_string(),
stage::ConfigValue::Bool(true),
)])),
config: Some(HashMap::from([
(
"internet_active".to_string(),
stage::ConfigValue::Bool(self.internet_active),
),
(
"use_net_settings".to_string(),
stage::ConfigValue::Bool(self.use_net_settings),
),
])),
resuts: None,
error: None,
}
}
pub fn update(&mut self, message: Message) -> stage::StageAction {
pub fn update(&mut self, message: Message) -> UpdateResult {
match message {
Message::Next => stage::StageAction::Next(self.gen_result()),
Message::Back => stage::StageAction::Back,
Message::StateChange(new_state) => {
self.state = new_state;
stage::StageAction::None
},
Message::UseSettingsTogle(toggle) => {
self.use_net_settings = toggle;
stage::StageAction::None
Message::CheckNetwork => {
self.state = State::Cheking;
UpdateResult::Task(Task::perform(check_connected(), Message::CheckCompleted))
}
Message::CheckCompleted(check_status) => {
match check_status {
CheckResult::Connected => {
self.internet_active = true;
self.state = State::Normal;
}
CheckResult::NoConnection => {
self.internet_active = false;
self.state = State::Normal;
}
CheckResult::CheckError => {
self.internet_active = false;
self.state = State::Normal;
}
}
UpdateResult::StageAction(stage::StageAction::None)
}
Message::Next => UpdateResult::StageAction(stage::StageAction::Next(self.gen_result())),
Message::Back => UpdateResult::StageAction(stage::StageAction::Back),
Message::UseSettingsTogle(use_net_settings) => {
self.use_net_settings = use_net_settings;
UpdateResult::StageAction(stage::StageAction::None)
}
}
}
pub fn view(&self) -> iced::Element<'_, Message> {
let next_button =
widget::button(widget::text(t!("button.next"))).on_press(Message::Next);
let back_button = widget::button(widget::text(t!("button.back"))).on_press(Message::Back);
let (next_button, back_button) = match self.state {
State::Cheking => (
widget::button(widget::text(t!("button.next"))),
widget::button(widget::text(t!("button.back"))),
),
State::Normal => (
widget::button(widget::text(t!("button.next"))).on_press(Message::Next),
widget::button(widget::text(t!("button.back"))).on_press(Message::Back),
),
};
let mut info_column = match self.state {
State::Cheking => widget::Column::new()
.push(
widget::container(apng(&self.spinner_frames))
.center_x(iced::Length::Fill)
.center_y(iced::Length::Fill),
)
.push(widget::text(t!("network.checking"))),
State::Normal => widget::Column::new(),
};
info_column = info_column.push(widget::text(t!("network.reuse_question")));
info_column = match self.state {
State::Cheking => info_column.push(
widget::checkbox(self.use_net_settings).label(t!("network.reuse_checkbox_caption")),
),
State::Normal => info_column.push(
widget::checkbox(self.use_net_settings)
.label(t!("network.reuse_checkbox_caption"))
.on_toggle(Message::UseSettingsTogle),
)
};
info_column = info_column
.align_x(Alignment::Center)
.padding(20)
.spacing(5);
widget::column![
widget::container(
widget::column![
widget::text(t!("network.reuse_question")),
widget::checkbox(self.use_net_settings)
.label(t!("network.reuse_checkbox_caption"))
.on_toggle(Message::UseSettingsTogle)
]
widget::container(info_column)
.height(iced::Length::Fill)
.width(iced::Length::Fill)
.align_x(Alignment::Center)
.padding(20)
.spacing(5)
)
.height(iced::Length::Fill)
.width(iced::Length::Fill)
.align_x(Alignment::Center)
.align_y(Alignment::Center),
.align_y(Alignment::Center),
widget::row![
back_button,
widget::space::horizontal(), // Pushes the right button to the far right
Binary file not shown.

After

Width:  |  Height:  |  Size: 146 KiB