Work on Network stage and toml config.
This commit is contained in:
Binary file not shown.
|
After Width: | Height: | Size: 251 KiB |
@@ -0,0 +1,3 @@
|
||||
|
||||
[network]
|
||||
reqire_network = true
|
||||
+3
-2
@@ -10,5 +10,6 @@
|
||||
"license.license": "This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.\n\nThis program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.\n\nYou should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.",
|
||||
"license.accept_text": "By pressing 'Accept' button you agreening to terms described above.",
|
||||
"license.button.accept": "Accept",
|
||||
"license.button.decline": "Decline"
|
||||
}
|
||||
"network.reuse_checkbox_caption": "Reuse settings?",
|
||||
"network.reuse_question": "Do you want to apply current network settings to installing system?"
|
||||
}
|
||||
+90
-18
@@ -27,12 +27,15 @@
|
||||
use iced::widget;
|
||||
use iced::Alignment;
|
||||
use std::collections::{HashMap};
|
||||
|
||||
use std::path::{PathBuf,Path};
|
||||
use std::str::FromStr;
|
||||
use std::process::ExitCode;
|
||||
|
||||
use iced::{Element, Task};
|
||||
|
||||
use crate::stage::{StageAction, KiraConfig};
|
||||
use crate::stages::license;
|
||||
use crate::stages::network;
|
||||
use crate::stages::welcome;
|
||||
use crate::stages::welcome::WelcomeStage;
|
||||
|
||||
@@ -47,12 +50,15 @@ enum Views {
|
||||
Start,
|
||||
Welcome(welcome::WelcomeStage),
|
||||
License(license::LicenseStage),
|
||||
Network(stages::network::NetworkStage),
|
||||
|
||||
}
|
||||
|
||||
enum Message {
|
||||
Start,
|
||||
Welcome(welcome::Message),
|
||||
License(license::Message)
|
||||
License(license::Message),
|
||||
Network(stages::network::Message)
|
||||
}
|
||||
|
||||
struct KiraState {
|
||||
@@ -61,30 +67,70 @@ struct KiraState {
|
||||
config: KiraConfig,
|
||||
}
|
||||
|
||||
const CONFIG_PATH_STR: &str = "kira_config.toml";
|
||||
|
||||
fn load_kira_config(config_path: &str) -> Result<toml::Table, Box<dyn std::error::Error>> {
|
||||
use std::fs;
|
||||
use toml::Table;
|
||||
// 1. Read the file content into a String
|
||||
let content = fs::read_to_string(config_path)?;
|
||||
|
||||
// 2. Parse the string into a Table
|
||||
let table: Table = content.parse()?;
|
||||
|
||||
println!("{:?}", table);
|
||||
Ok(table)
|
||||
}
|
||||
|
||||
impl KiraState {
|
||||
fn new(toml_config: toml::Table) -> Self {
|
||||
|
||||
Self {
|
||||
fn boot() -> (Self, Task<Message>) {
|
||||
(Self {
|
||||
current_view: Views::Start,
|
||||
toml_config: toml_config,
|
||||
toml_config: toml::Table::new(),
|
||||
config: KiraConfig { config_trail: Vec::new() }
|
||||
}
|
||||
}, Task::done(Message::Start))
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// impl KiraState {
|
||||
// fn new(toml_config: toml::Table) -> Self {
|
||||
|
||||
// Self {
|
||||
// current_view: Views::Start,
|
||||
// toml_config: toml_config,
|
||||
// config: KiraConfig { config_trail: Vec::new() }
|
||||
// }
|
||||
// }
|
||||
|
||||
// }
|
||||
|
||||
|
||||
|
||||
fn view(k_state: &KiraState) -> Element<'_, Message> {
|
||||
match &k_state.current_view {
|
||||
Views::Start => Element::new(widget::space()) ,
|
||||
Views::Welcome(wellcome_stage) => wellcome_stage.view().map(Message::Welcome),
|
||||
Views::License(license_stage) => license_stage.view().map(Message::License),
|
||||
Views::Network(network_stage) => network_stage.view().map(Message::Network),
|
||||
}
|
||||
}
|
||||
|
||||
fn update(k_state: &mut KiraState, message: Message) -> Task<Message> {
|
||||
match message {
|
||||
Message::Start => {
|
||||
match load_kira_config(CONFIG_PATH_STR) {
|
||||
Ok(conf) => {
|
||||
println!("Config loaded!");
|
||||
k_state.toml_config = conf;
|
||||
k_state.current_view = Views::Welcome(WelcomeStage::new());
|
||||
Task::none()
|
||||
},
|
||||
Err(ex) => {
|
||||
println!("Error reading config {}: {}", CONFIG_PATH_STR, ex);
|
||||
iced::exit()
|
||||
}
|
||||
}
|
||||
},
|
||||
Message::Welcome(wlc_msg) => {
|
||||
if let Views::Welcome(wlc_view) = &mut k_state.current_view {
|
||||
let action = wlc_view.update(wlc_msg);
|
||||
@@ -101,7 +147,8 @@ fn update(k_state: &mut KiraState, message: Message) -> Task<Message> {
|
||||
match action {
|
||||
StageAction::Next(license_res) => {
|
||||
k_state.config.config_trail.push(license_res);
|
||||
iced::exit()
|
||||
k_state.current_view = Views::Network(network::NetworkStage::new(&k_state.toml_config));
|
||||
Task::none()
|
||||
},
|
||||
StageAction::Abort(_) => iced::exit(),
|
||||
StageAction::Back => iced::exit(),
|
||||
@@ -111,6 +158,15 @@ fn update(k_state: &mut KiraState, message: Message) -> Task<Message> {
|
||||
else {
|
||||
Task::none()
|
||||
}
|
||||
},
|
||||
Message::Network(network_message) => {
|
||||
if let Views::Network(network_view) = &mut k_state.current_view {
|
||||
Task::none()
|
||||
}
|
||||
else {
|
||||
Task::none()
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -119,18 +175,34 @@ fn update(k_state: &mut KiraState, message: Message) -> Task<Message> {
|
||||
// pub fn main_interface() -> iced::Result {
|
||||
// iced::run(WellcomeStage::update, WellcomeStage::view)
|
||||
// }
|
||||
pub fn main() -> iced::Result {
|
||||
use toml;
|
||||
let app_init = || {
|
||||
let mut k_state = KiraState::new(toml::Table::new());
|
||||
k_state.current_view = Views::Welcome(WelcomeStage::new());
|
||||
k_state
|
||||
};
|
||||
pub fn main() -> ExitCode {
|
||||
|
||||
iced::application(app_init, update, view)
|
||||
|
||||
// let app_init = || {
|
||||
// let mut k_state = KiraState::default()
|
||||
// k_state.current_view = Views::Welcome(WelcomeStage::new());
|
||||
// k_stateapp_init
|
||||
// };
|
||||
|
||||
let iced_result = iced::application(KiraState::boot, update, view)
|
||||
.window(iced::window::Settings {
|
||||
icon: Some(
|
||||
iced::window::icon::from_file_data(
|
||||
include_bytes!("icon.png"),
|
||||
None,
|
||||
)
|
||||
.expect("icon should be a valid PNG"),
|
||||
),
|
||||
..Default::default()
|
||||
})
|
||||
.centered()
|
||||
.theme(theme::main_theme())
|
||||
.run()
|
||||
.run();
|
||||
|
||||
match iced_result {
|
||||
Ok(()) => ExitCode::SUCCESS,
|
||||
Err(_) => ExitCode::from(42), // Custom error code
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
+2
-1
@@ -16,4 +16,5 @@
|
||||
|
||||
|
||||
pub mod welcome;
|
||||
pub mod license;
|
||||
pub mod license;
|
||||
pub mod network;
|
||||
@@ -0,0 +1,158 @@
|
||||
// <Kira Installer - universal Linux installer.>
|
||||
// Copyright (C) <2026> <Kira Foundation>
|
||||
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
/*
|
||||
This is Network stage. Chiking if internet is active and propose to configure it if
|
||||
it needed for installation to process.
|
||||
*/
|
||||
|
||||
use toml::Table;
|
||||
use iced::{Alignment, widget};
|
||||
|
||||
use rust_i18n::t;
|
||||
use std::collections::HashMap;
|
||||
|
||||
use crate::stage;
|
||||
use crate::stage::StageResult;
|
||||
|
||||
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum State {
|
||||
Init,
|
||||
Cheking,
|
||||
ConnOK,
|
||||
ConnBad,
|
||||
CheckFailed,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct NetworkStage {
|
||||
internet_active: bool,
|
||||
state: State,
|
||||
use_net_settings: bool,
|
||||
reqire_network: bool,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum Message {
|
||||
Next,
|
||||
Back,
|
||||
StateChange(State),
|
||||
UseSettingsTogle(bool)
|
||||
}
|
||||
|
||||
|
||||
|
||||
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())
|
||||
{
|
||||
println!("Config value reqire_network read {}", reqire_network_conf);
|
||||
reqire_network = reqire_network_conf;
|
||||
}
|
||||
else {
|
||||
println!("Error parsing network config. Using default values.");
|
||||
}
|
||||
|
||||
Self {
|
||||
internet_active: false,
|
||||
state: State::Init,
|
||||
use_net_settings: false,
|
||||
reqire_network: reqire_network
|
||||
}
|
||||
}
|
||||
|
||||
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),
|
||||
)])),
|
||||
resuts: None,
|
||||
error: None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn update(&mut self, message: Message) -> stage::StageAction {
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
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)
|
||||
]
|
||||
.align_x(Alignment::Center)
|
||||
.padding(20)
|
||||
.spacing(5)
|
||||
)
|
||||
.height(iced::Length::Fill)
|
||||
.width(iced::Length::Fill)
|
||||
.align_x(Alignment::Center)
|
||||
.align_y(Alignment::Center),
|
||||
widget::row![
|
||||
back_button,
|
||||
widget::space::horizontal(), // Pushes the right button to the far right
|
||||
next_button
|
||||
]
|
||||
.width(iced::Length::Fill)
|
||||
.align_y(Alignment::End)
|
||||
.padding(10)
|
||||
.spacing(10),
|
||||
]
|
||||
.align_x(Alignment::Center)
|
||||
.into()
|
||||
}
|
||||
}
|
||||
@@ -111,7 +111,12 @@ impl WelcomeStage {
|
||||
self.locale = Some(loc);
|
||||
StageAction::None
|
||||
}
|
||||
Message::Exit => StageAction::Back,
|
||||
Message::Exit => StageAction::Abort(StageResult {
|
||||
name: "welcome".to_string(),
|
||||
config: None,
|
||||
resuts: None,
|
||||
error: None,
|
||||
}),
|
||||
Message::Next => StageAction::Next(self.gen_result()),
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user