More work on Network stage.

This commit is contained in:
2026-04-24 00:38:44 +02:00
parent a83dbc27f2
commit 632c6f7f98
6 changed files with 90 additions and 56 deletions
Generated
-1
View File
@@ -2045,7 +2045,6 @@ dependencies = [
"iced", "iced",
"iced_moving_picture", "iced_moving_picture",
"rust-i18n", "rust-i18n",
"smol",
"toml 1.1.2+spec-1.1.0", "toml 1.1.2+spec-1.1.0",
] ]
-1
View File
@@ -8,7 +8,6 @@ blocking = "1.6.2"
iced = { version = "0.14", features = ["smol", "image"] } iced = { version = "0.14", features = ["smol", "image"] }
iced_moving_picture = "0" iced_moving_picture = "0"
rust-i18n = "3" rust-i18n = "3"
smol = "2.0.2"
toml = "1" toml = "1"
[profile.release] [profile.release]
+6 -2
View File
@@ -8,10 +8,14 @@
"wellcome.text": "Welcome to Kira Installer!", "wellcome.text": "Welcome to Kira Installer!",
"wellcome.choose_language": "Please select language to use during istalation!", "wellcome.choose_language": "Please select language to use during istalation!",
"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.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.accept_text": "By pressing 'Accept' button you agreening to terms described above:",
"license.button.accept": "Accept", "license.button.accept": "Accept",
"license.button.decline": "Decline", "license.button.decline": "Decline",
"network.reuse_checkbox_caption": "Reuse settings?", "network.reuse_checkbox_caption": "Reuse settings?",
"network.reuse_question": "Do you want to apply current network settings to installing system?", "network.reuse_question": "Do you want to apply current network settings to installing system?",
"network.checking": "Checking network connectivity, please wait..." "network.checking": "Checking network connectivity, please wait...",
"network.ok": "Network connection active!",
"network.no_connection": "Network inactive.",
"network.check_error": "Error while cheking network connection.",
"network.button.check": "Check Network"
} }
+4 -2
View File
@@ -26,7 +26,7 @@ use iced::{Alignment, widget};
use rust_i18n::t; use rust_i18n::t;
use std::collections::HashMap; use std::collections::HashMap;
use crate::stage; use crate::{stage, theme};
use crate::stage::StageResult; use crate::stage::StageResult;
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
@@ -81,7 +81,9 @@ impl LicenseStage {
widget::column![ widget::column![
widget::container(widget::column![ widget::container(widget::column![
widget::text(t!("license.accept_text")), widget::text(t!("license.accept_text")),
widget::text(t!("license.license")) widget::container(widget::text(t!("license.license")))
.padding(10)
.style(theme::text_with_border)
].align_x(Alignment::Center).padding(20).spacing(5)) ].align_x(Alignment::Center).padding(20).spacing(5))
.height(iced::Length::Fill) .height(iced::Length::Fill)
.width(iced::Length::Fill) .width(iced::Length::Fill)
+39 -29
View File
@@ -22,7 +22,6 @@
use iced::{Alignment, Task, widget}; use iced::{Alignment, Task, widget};
use iced_moving_picture::widget::apng; use iced_moving_picture::widget::apng;
use rust_i18n::t; use rust_i18n::t;
use smol;
use std::collections::HashMap; use std::collections::HashMap;
use toml::Table; use toml::Table;
@@ -30,6 +29,8 @@ use crate::stage;
use crate::stage::StageResult; use crate::stage::StageResult;
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
#[derive(PartialEq, Eq)]
pub enum State { pub enum State {
Cheking, Cheking,
Normal, Normal,
@@ -49,6 +50,7 @@ pub struct NetworkStage {
use_net_settings: bool, use_net_settings: bool,
reqire_network: bool, reqire_network: bool,
spinner_frames: apng::Frames, spinner_frames: apng::Frames,
status_message: String,
} }
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
@@ -69,6 +71,8 @@ pub enum UpdateResult {
fn check_connection_blocking() -> CheckResult { fn check_connection_blocking() -> CheckResult {
use std::process::Command; use std::process::Command;
std::thread::sleep(std::time::Duration::from_secs(5));
match Command::new("nm-online").arg("-q").status() { match Command::new("nm-online").arg("-q").status() {
Ok(status) => { Ok(status) => {
if status.success() { if status.success() {
@@ -115,6 +119,7 @@ impl NetworkStage {
use_net_settings: false, use_net_settings: false,
reqire_network: reqire_network, reqire_network: reqire_network,
spinner_frames: spinner_frames, spinner_frames: spinner_frames,
status_message: t!("network.checking").into(),
} }
} }
@@ -140,6 +145,7 @@ impl NetworkStage {
match message { match message {
Message::CheckNetwork => { Message::CheckNetwork => {
self.state = State::Cheking; self.state = State::Cheking;
self.status_message = t!("network.checking").into();
UpdateResult::Task(Task::perform(check_connected(), Message::CheckCompleted)) UpdateResult::Task(Task::perform(check_connected(), Message::CheckCompleted))
} }
Message::CheckCompleted(check_status) => { Message::CheckCompleted(check_status) => {
@@ -147,14 +153,17 @@ impl NetworkStage {
CheckResult::Connected => { CheckResult::Connected => {
self.internet_active = true; self.internet_active = true;
self.state = State::Normal; self.state = State::Normal;
self.status_message = t!("network.ok").into();
} }
CheckResult::NoConnection => { CheckResult::NoConnection => {
self.internet_active = false; self.internet_active = false;
self.state = State::Normal; self.state = State::Normal;
self.status_message = t!("network.no_connection").into();
} }
CheckResult::CheckError => { CheckResult::CheckError => {
self.internet_active = false; self.internet_active = false;
self.state = State::Normal; self.state = State::Normal;
self.status_message = t!("network.check_error").into();
} }
} }
UpdateResult::StageAction(stage::StageAction::None) UpdateResult::StageAction(stage::StageAction::None)
@@ -169,45 +178,46 @@ impl NetworkStage {
} }
pub fn view(&self) -> iced::Element<'_, Message> { pub fn view(&self) -> iced::Element<'_, Message> {
let (next_button, back_button) = match self.state { let next_button = if (self.state == State::Cheking) || (!self.internet_active && self.reqire_network) {
widget::button(widget::text(t!("button.next")))
}
else {
widget::button(widget::text(t!("button.next"))).on_press(Message::Next)
};
let (back_button, check_button, reuse_checkbox) = match self.state {
State::Cheking => ( State::Cheking => (
widget::button(widget::text(t!("button.next"))),
widget::button(widget::text(t!("button.back"))), widget::button(widget::text(t!("button.back"))),
), widget::button(widget::text(t!("network.button.check"))),
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")), widget::checkbox(self.use_net_settings).label(t!("network.reuse_checkbox_caption")),
), ),
State::Normal => info_column.push( State::Normal => (
widget::button(widget::text(t!("button.back"))).on_press(Message::Back),
widget::button(widget::text(t!("network.button.check")))
.on_press(Message::CheckNetwork),
widget::checkbox(self.use_net_settings) widget::checkbox(self.use_net_settings)
.label(t!("network.reuse_checkbox_caption")) .label(t!("network.reuse_checkbox_caption"))
.on_toggle(Message::UseSettingsTogle), .on_toggle(Message::UseSettingsTogle),
) ),
}; };
info_column = info_column let spinner_container = match self.state {
State::Cheking => widget::container(apng(&self.spinner_frames)),
State::Normal => widget::container(widget::space().height(128).width(128)),
};
let info_column = widget::column![
spinner_container,
widget::row![widget::text(self.status_message.as_str()), check_button]
.align_y(Alignment::Center)
.padding(10)
.spacing(10),
widget::text(t!("network.reuse_question")),
reuse_checkbox
]
.align_x(Alignment::Center) .align_x(Alignment::Center)
.padding(20) .padding(20)
.spacing(5); .spacing(10);
widget::column![ widget::column![
widget::container(info_column) widget::container(info_column)
+24 -4
View File
@@ -14,15 +14,13 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>. // along with this program. If not, see <https://www.gnu.org/licenses/>.
/* /*
This file is supposed to be used as theme source for the installer. This file is supposed to be used as theme source for the installer.
Modify it to your liking. Modify it to your liking.
*/ */
use iced::{color, Theme}; use iced::widget::container;
use iced::{Border, Color, Theme, color, Background};
// Function returns theme to be used by installer // Function returns theme to be used by installer
pub fn main_theme() -> Theme { pub fn main_theme() -> Theme {
@@ -30,3 +28,25 @@ pub fn main_theme() -> Theme {
pl.primary = color!(0xFFD700); pl.primary = color!(0xFFD700);
return Theme::custom("Kira Theme", pl); return Theme::custom("Kira Theme", pl);
} }
pub fn change_lightnes(c: &Color, factor: f32) -> Color {
let mut res = c.clone();
res.r = (res.r + res.r*factor).clamp(0.0, 1.0);
res.g = (res.g + res.g*factor).clamp(0.0, 1.0);
res.b = (res.b + res.b*factor).clamp(0.0, 1.0);
res
}
pub fn text_with_border(_theme: &Theme) -> container::Style {
container::Style {
border: Border {
color: Color::from_rgb8(120, 98, 10),
width: 2.0,
radius: 7.into(),
},
background: Some(Background::Color(change_lightnes(&_theme.palette().background, 0.3))),
..container::Style::default()
}
}