2024-02-18 16:39:04 +01:00
|
|
|
use crate::config::DISTRO_ICON;
|
2024-02-16 16:16:45 +01:00
|
|
|
use std::cell::RefCell;
|
2024-02-14 16:32:01 +01:00
|
|
|
// Use libraries
|
|
|
|
use adw::prelude::*;
|
|
|
|
use adw::*;
|
2024-08-03 02:41:51 +02:00
|
|
|
use gtk::glib;
|
|
|
|
use gtk::glib::*;
|
2024-02-16 22:21:09 +01:00
|
|
|
/// Use all gtk4 libraries (gtk4 -> gtk because cargo)
|
|
|
|
/// Use all libadwaita libraries (libadwaita -> adw because cargo)
|
|
|
|
use gtk::*;
|
2024-02-14 16:32:01 +01:00
|
|
|
use vte::prelude::*;
|
|
|
|
use vte::*;
|
|
|
|
|
2024-02-20 16:11:38 +01:00
|
|
|
use gnome_desktop::*;
|
2024-02-18 18:28:14 +01:00
|
|
|
|
2024-02-14 16:32:01 +01:00
|
|
|
use crate::done_page::done_page;
|
|
|
|
|
2024-02-16 22:21:09 +01:00
|
|
|
use std::process::Command;
|
2024-02-14 16:32:01 +01:00
|
|
|
|
2024-02-20 16:11:38 +01:00
|
|
|
use std::{fs};
|
2024-02-14 16:32:01 +01:00
|
|
|
use std::path::Path;
|
2024-02-16 16:16:45 +01:00
|
|
|
use std::rc::Rc;
|
2024-02-14 16:32:01 +01:00
|
|
|
|
2024-02-16 22:21:09 +01:00
|
|
|
use crate::manual_partitioning::DriveMount;
|
2024-02-17 12:47:32 +01:00
|
|
|
use duct::*;
|
2024-02-19 18:44:10 +01:00
|
|
|
use serde::*;
|
2024-02-16 16:16:45 +01:00
|
|
|
|
2024-02-16 22:21:09 +01:00
|
|
|
#[derive(PartialEq, Debug, Eq, Hash, Clone, Serialize, Deserialize)]
|
|
|
|
struct CrypttabEntry {
|
|
|
|
partition: String,
|
|
|
|
password: String,
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn install_page(
|
|
|
|
done_main_box: >k::Box,
|
|
|
|
install_main_box: >k::Box,
|
|
|
|
content_stack: >k::Stack,
|
|
|
|
window: &adw::ApplicationWindow,
|
|
|
|
manual_drive_mount_array: &Rc<RefCell<Vec<DriveMount>>>,
|
|
|
|
) {
|
2024-02-20 16:11:38 +01:00
|
|
|
|
2024-02-17 14:52:07 +01:00
|
|
|
let mut _iter_count = 0;
|
|
|
|
_iter_count = 0;
|
2024-02-16 22:21:09 +01:00
|
|
|
let mut unlocked_array: Vec<String> = Default::default();
|
2024-02-19 18:44:10 +01:00
|
|
|
manual_drive_mount_array
|
|
|
|
.borrow_mut()
|
|
|
|
.sort_by_key(|p| p.clone().mountpoint);
|
2024-02-16 22:21:09 +01:00
|
|
|
for partitions in manual_drive_mount_array.borrow_mut().iter() {
|
|
|
|
let new_crypt = if partitions.mountpoint != "/"
|
|
|
|
&& !unlocked_array.contains(&partitions.partition)
|
|
|
|
&& Command::new("sudo")
|
|
|
|
.arg("/usr/lib/pika/pika-installer-gtk4/scripts/partition-utility.sh")
|
|
|
|
.arg("has_encryption")
|
|
|
|
.arg(&partitions.partition)
|
|
|
|
.output()
|
|
|
|
.expect("failed to execute process")
|
|
|
|
.status
|
|
|
|
.success()
|
|
|
|
{
|
|
|
|
let crypttab_password_listbox = gtk::ListBox::builder()
|
|
|
|
.margin_top(10)
|
|
|
|
.margin_bottom(10)
|
|
|
|
.margin_start(10)
|
|
|
|
.margin_end(10)
|
|
|
|
.build();
|
|
|
|
crypttab_password_listbox.add_css_class("boxed-list");
|
|
|
|
let crypttab_password = adw::PasswordEntryRow::builder()
|
2024-02-20 16:11:38 +01:00
|
|
|
.title(t!("luks_password_for").to_string() + &partitions.partition)
|
2024-02-16 22:21:09 +01:00
|
|
|
.build();
|
2024-02-17 12:47:32 +01:00
|
|
|
crypttab_password.set_show_apply_button(true);
|
2024-02-16 22:21:09 +01:00
|
|
|
crypttab_password_listbox.append(&crypttab_password);
|
|
|
|
let crypttab_dialog = adw::MessageDialog::builder()
|
|
|
|
.transient_for(window)
|
|
|
|
.hide_on_close(true)
|
|
|
|
.extra_child(&crypttab_password_listbox)
|
|
|
|
.width_request(400)
|
|
|
|
.height_request(200)
|
|
|
|
.heading(
|
2024-02-20 16:11:38 +01:00
|
|
|
t!("luks_how_should").to_string()
|
2024-02-16 22:21:09 +01:00
|
|
|
+ &partitions.partition
|
2024-02-20 16:11:38 +01:00
|
|
|
+ &t!("be_added_crypttab"),
|
2024-02-16 22:21:09 +01:00
|
|
|
)
|
|
|
|
.build();
|
2024-02-20 16:11:38 +01:00
|
|
|
crypttab_dialog.add_response("crypttab_dialog_boot", &t!("unlock_boot_manually"));
|
|
|
|
crypttab_dialog.add_response("crypttab_dialog_auto", &t!("unlock_boot_manual"));
|
2024-02-16 22:21:09 +01:00
|
|
|
crypttab_dialog.set_response_enabled("crypttab_dialog_auto", false);
|
2024-02-17 12:47:32 +01:00
|
|
|
crypttab_password.connect_apply(clone!(@weak crypttab_password, @strong partitions, @weak crypttab_dialog => move |_| {
|
2024-02-16 22:21:09 +01:00
|
|
|
let (luks_manual_password_sender, luks_manual_password_receiver) = async_channel::unbounded();
|
|
|
|
let luks_manual_password_sender = luks_manual_password_sender.clone();
|
2024-02-17 12:47:32 +01:00
|
|
|
let luks_password = crypttab_password.text().to_string();
|
2024-02-16 22:21:09 +01:00
|
|
|
|
|
|
|
gio::spawn_blocking(clone!(@strong crypttab_password, @strong partitions => move || {
|
2024-02-17 12:47:32 +01:00
|
|
|
let result = cmd!("sudo", "/usr/lib/pika/pika-installer-gtk4/scripts/partition-utility.sh", "test_luks_passwd", &partitions.partition, luks_password).run();
|
|
|
|
if result.is_ok() {
|
2024-02-16 22:21:09 +01:00
|
|
|
luks_manual_password_sender
|
|
|
|
.send_blocking(false)
|
|
|
|
.expect("The channel needs to be open.");
|
|
|
|
} else {
|
|
|
|
luks_manual_password_sender
|
|
|
|
.send_blocking(true)
|
|
|
|
.expect("The channel needs to be open.");
|
|
|
|
}
|
|
|
|
}));
|
|
|
|
let luks_manual_password_main_context = MainContext::default();
|
|
|
|
// The main loop executes the asynchronous block
|
|
|
|
luks_manual_password_main_context.spawn_local(clone!(@weak crypttab_dialog => async move {
|
|
|
|
while let Ok(state) = luks_manual_password_receiver.recv().await {
|
|
|
|
crypttab_dialog.set_response_enabled("crypttab_dialog_auto", !state);
|
|
|
|
}
|
|
|
|
}));
|
|
|
|
}));
|
|
|
|
|
|
|
|
let partition_final = partitions.partition.clone();
|
|
|
|
let partition_final2 = partitions.partition.clone();
|
|
|
|
crypttab_dialog.choose(None::<&gio::Cancellable>, move |choice| {
|
|
|
|
if choice == "crypttab_dialog_auto" {
|
|
|
|
let crypttab_entry = CrypttabEntry {
|
|
|
|
partition: partition_final2,
|
|
|
|
password: (&crypttab_password.text()).to_string(),
|
|
|
|
};
|
|
|
|
fs::write(
|
|
|
|
"/tmp/pika-installer-gtk4-target-manual-luks-p".to_owned()
|
2024-02-17 14:52:07 +01:00
|
|
|
+ &_iter_count.to_string()
|
2024-02-16 22:21:09 +01:00
|
|
|
+ ".json",
|
|
|
|
serde_json::to_string(&crypttab_entry).unwrap(),
|
|
|
|
)
|
|
|
|
.expect("Unable to write file");
|
|
|
|
} else {
|
|
|
|
let crypttab_entry = CrypttabEntry {
|
|
|
|
partition: partition_final2,
|
|
|
|
password: (&"").to_string(),
|
|
|
|
};
|
|
|
|
fs::write(
|
|
|
|
"/tmp/pika-installer-gtk4-target-manual-luks-p".to_owned()
|
2024-02-17 14:52:07 +01:00
|
|
|
+ &_iter_count.to_string()
|
2024-02-16 22:21:09 +01:00
|
|
|
+ ".json",
|
|
|
|
serde_json::to_string(&crypttab_entry).unwrap(),
|
|
|
|
)
|
|
|
|
.expect("Unable to write file");
|
|
|
|
}
|
|
|
|
});
|
|
|
|
partition_final
|
|
|
|
} else {
|
|
|
|
String::from("")
|
|
|
|
};
|
|
|
|
fs::write(
|
|
|
|
"/tmp/pika-installer-gtk4-target-manual-p".to_owned()
|
2024-02-17 14:52:07 +01:00
|
|
|
+ &_iter_count.to_string()
|
2024-02-16 22:21:09 +01:00
|
|
|
+ ".json",
|
|
|
|
serde_json::to_string(partitions).unwrap(),
|
|
|
|
)
|
|
|
|
.expect("Unable to write file");
|
|
|
|
if !new_crypt.is_empty() {
|
|
|
|
unlocked_array.push(new_crypt);
|
|
|
|
}
|
|
|
|
dbg!(&unlocked_array);
|
2024-02-17 14:52:07 +01:00
|
|
|
_iter_count += 1;
|
2024-02-16 22:21:09 +01:00
|
|
|
}
|
2024-02-14 16:32:01 +01:00
|
|
|
|
|
|
|
// create the bottom box for next and back buttons
|
|
|
|
let bottom_box = gtk::Box::builder()
|
|
|
|
.orientation(Orientation::Horizontal)
|
|
|
|
.valign(gtk::Align::End)
|
|
|
|
.vexpand(true)
|
|
|
|
.build();
|
|
|
|
|
|
|
|
// Next and back button
|
|
|
|
let bottom_back_button = gtk::Button::builder()
|
2024-02-20 16:11:38 +01:00
|
|
|
.label(t!("back"))
|
2024-02-14 16:32:01 +01:00
|
|
|
.margin_top(15)
|
|
|
|
.margin_bottom(15)
|
|
|
|
.margin_start(15)
|
|
|
|
.margin_end(15)
|
|
|
|
.halign(gtk::Align::Start)
|
|
|
|
.hexpand(true)
|
|
|
|
.build();
|
|
|
|
|
|
|
|
// / bottom_box appends
|
|
|
|
//// Add the next and back buttons
|
|
|
|
bottom_box.append(&bottom_back_button);
|
|
|
|
|
|
|
|
let install_nested_stack = gtk::Stack::builder()
|
|
|
|
.transition_type(StackTransitionType::SlideLeftRight)
|
|
|
|
.build();
|
|
|
|
|
|
|
|
let install_confirm_box = gtk::Box::builder()
|
|
|
|
.orientation(Orientation::Vertical)
|
|
|
|
.build();
|
|
|
|
|
|
|
|
// the header box for the install page
|
|
|
|
let install_confirm_header_box = gtk::Box::builder()
|
|
|
|
.orientation(Orientation::Horizontal)
|
|
|
|
.build();
|
|
|
|
|
|
|
|
// the header text for the install page
|
|
|
|
let install_confirm_header_text = gtk::Label::builder()
|
2024-02-20 16:11:38 +01:00
|
|
|
.label(t!("sit_back_relax"))
|
2024-02-14 16:32:01 +01:00
|
|
|
.halign(gtk::Align::End)
|
|
|
|
.hexpand(true)
|
|
|
|
.margin_top(15)
|
|
|
|
.margin_bottom(15)
|
|
|
|
.margin_start(15)
|
|
|
|
.margin_end(5)
|
|
|
|
.build();
|
|
|
|
install_confirm_header_text.add_css_class("header_sized_text");
|
|
|
|
|
|
|
|
// the header icon for the install icon
|
|
|
|
let install_confirm_header_icon = gtk::Spinner::builder()
|
|
|
|
.halign(gtk::Align::Start)
|
|
|
|
.hexpand(true)
|
|
|
|
.margin_top(15)
|
|
|
|
.margin_bottom(15)
|
|
|
|
.margin_start(0)
|
|
|
|
.margin_end(15)
|
|
|
|
.build();
|
|
|
|
install_confirm_header_icon.start();
|
|
|
|
|
|
|
|
// make install selection box for choosing installation or live media
|
|
|
|
let install_confirm_selection_box = gtk::Box::builder()
|
|
|
|
.orientation(Orientation::Vertical)
|
|
|
|
.halign(gtk::Align::Fill)
|
|
|
|
.valign(gtk::Align::Center)
|
|
|
|
.vexpand(true)
|
|
|
|
.hexpand(true)
|
|
|
|
.build();
|
|
|
|
|
|
|
|
let install_confirm_details_boxed_list = gtk::ListBox::builder()
|
|
|
|
.margin_top(15)
|
|
|
|
.margin_bottom(15)
|
|
|
|
.margin_start(256)
|
|
|
|
.margin_end(256)
|
|
|
|
.halign(gtk::Align::Fill)
|
|
|
|
.valign(gtk::Align::Center)
|
|
|
|
.hexpand(true)
|
|
|
|
.build();
|
|
|
|
install_confirm_details_boxed_list.add_css_class("boxed-list");
|
|
|
|
|
2024-02-20 16:11:38 +01:00
|
|
|
let locale_name_cli =
|
|
|
|
Command::new("/usr/lib/pika/pika-installer-gtk4/scripts/locale-name.py")
|
|
|
|
.arg(fs::read_to_string("/tmp/pika-installer-gtk4-lang.txt").expect("Unable to read file"))
|
|
|
|
.output()
|
|
|
|
.expect("failed to execute process");
|
|
|
|
let locale_name = String::from_utf8(locale_name_cli.stdout).unwrap();
|
|
|
|
|
2024-02-14 16:32:01 +01:00
|
|
|
let install_confirm_detail_language = adw::ActionRow::builder()
|
2024-02-20 16:11:38 +01:00
|
|
|
.title(t!("language_detail"))
|
|
|
|
.subtitle(&locale_name)
|
2024-02-14 16:32:01 +01:00
|
|
|
.build();
|
|
|
|
install_confirm_detail_language.add_css_class("property");
|
|
|
|
|
|
|
|
let install_confirm_detail_timezone = adw::ActionRow::builder()
|
2024-02-20 16:11:38 +01:00
|
|
|
.title(t!("timezone_detail"))
|
2024-02-16 22:21:09 +01:00
|
|
|
.subtitle(
|
|
|
|
fs::read_to_string("/tmp/pika-installer-gtk4-timezone.txt")
|
|
|
|
.expect("Unable to read file"),
|
|
|
|
)
|
2024-02-14 16:32:01 +01:00
|
|
|
.build();
|
|
|
|
install_confirm_detail_timezone.add_css_class("property");
|
|
|
|
|
|
|
|
let install_confirm_detail_keyboard = adw::ActionRow::builder()
|
2024-02-20 16:11:38 +01:00
|
|
|
.title(t!("keyboard_detail"))
|
2024-02-16 22:21:09 +01:00
|
|
|
.subtitle(
|
2024-02-20 16:11:38 +01:00
|
|
|
gnome_desktop::XkbInfo::new()
|
|
|
|
.layout_info(&fs::read_to_string("/tmp/pika-installer-gtk4-keyboard.txt")
|
|
|
|
.expect("Unable to read file"))
|
|
|
|
.unwrap()
|
|
|
|
.0
|
2024-08-03 02:41:51 +02:00
|
|
|
.unwrap().to_string(),
|
2024-02-16 22:21:09 +01:00
|
|
|
)
|
2024-02-14 16:32:01 +01:00
|
|
|
.build();
|
|
|
|
install_confirm_detail_keyboard.add_css_class("property");
|
|
|
|
|
|
|
|
if Path::new("/tmp/pika-installer-gtk4-target-manual.txt").exists() {
|
2024-02-16 16:16:45 +01:00
|
|
|
//install_confirm_detail_target.set_subtitle(&fs::read_to_string("/tmp/pika-installer-gtk4-target-manual.txt").expect("Unable to read file"));
|
|
|
|
install_confirm_details_boxed_list.append(&install_confirm_detail_language);
|
|
|
|
install_confirm_details_boxed_list.append(&install_confirm_detail_timezone);
|
|
|
|
install_confirm_details_boxed_list.append(&install_confirm_detail_keyboard);
|
|
|
|
for partitions in manual_drive_mount_array.borrow_mut().iter() {
|
|
|
|
let confirm_row = adw::ActionRow::builder()
|
2024-02-16 22:21:09 +01:00
|
|
|
.title(
|
|
|
|
"/dev/".to_owned()
|
|
|
|
+ &partitions.partition
|
2024-02-20 16:11:38 +01:00
|
|
|
+ &t!("mounted_on_detail")
|
2024-02-19 18:44:10 +01:00
|
|
|
+ &partitions.mountpoint,
|
2024-02-16 22:21:09 +01:00
|
|
|
)
|
2024-02-16 16:16:45 +01:00
|
|
|
.build();
|
|
|
|
install_confirm_details_boxed_list.append(&confirm_row);
|
|
|
|
}
|
2024-02-14 16:32:01 +01:00
|
|
|
} else {
|
2024-02-19 18:44:10 +01:00
|
|
|
let install_confirm_detail_target = adw::ActionRow::builder()
|
2024-02-20 16:11:38 +01:00
|
|
|
.title(t!("install_target_detail"))
|
2024-02-19 18:44:10 +01:00
|
|
|
.build();
|
2024-02-16 22:21:09 +01:00
|
|
|
install_confirm_detail_target.set_subtitle(
|
|
|
|
&fs::read_to_string("/tmp/pika-installer-gtk4-target-auto.txt")
|
|
|
|
.expect("Unable to read file"),
|
|
|
|
);
|
2024-02-16 16:16:45 +01:00
|
|
|
install_confirm_detail_target.add_css_class("property");
|
2024-02-16 22:21:09 +01:00
|
|
|
let target_block_device = &fs::read_to_string("/tmp/pika-installer-gtk4-target-auto.txt")
|
|
|
|
.expect("Unable to read file");
|
2024-02-14 16:32:01 +01:00
|
|
|
let target_size_cli = Command::new("sudo")
|
|
|
|
.arg("/usr/lib/pika/pika-installer-gtk4/scripts/partition-utility.sh")
|
|
|
|
.arg("get_block_size")
|
|
|
|
.arg(target_block_device)
|
|
|
|
.output()
|
|
|
|
.expect("failed to execute process");
|
2024-02-16 22:21:09 +01:00
|
|
|
let target_size = String::from_utf8(target_size_cli.stdout)
|
|
|
|
.expect("Failed to create float")
|
|
|
|
.trim()
|
|
|
|
.parse::<f64>()
|
|
|
|
.unwrap();
|
2024-02-17 14:52:07 +01:00
|
|
|
let mut _target_p3_size = 0.0;
|
2024-02-14 16:32:01 +01:00
|
|
|
if (target_size * 40.0) / 100.0 >= 150000000000.0 {
|
2024-02-17 14:52:07 +01:00
|
|
|
_target_p3_size = 150000000000.0;
|
2024-02-14 16:32:01 +01:00
|
|
|
} else if (target_size * 40.0) / 100.0 <= 36507222016.0 {
|
2024-02-17 14:52:07 +01:00
|
|
|
_target_p3_size = 36507222016.0
|
2024-02-14 16:32:01 +01:00
|
|
|
} else {
|
2024-02-17 14:52:07 +01:00
|
|
|
_target_p3_size = (target_size * 40.0) / 100.0;
|
2024-02-14 16:32:01 +01:00
|
|
|
}
|
2024-02-17 14:52:07 +01:00
|
|
|
let target_p4_size = target_size - (_target_p3_size + 1536.0);
|
2024-02-14 16:32:01 +01:00
|
|
|
if Path::new("/tmp/pika-installer-p3-size.txt").exists() {
|
2024-02-16 22:21:09 +01:00
|
|
|
fs::remove_file("/tmp/pika-installer-p3-size.txt")
|
|
|
|
.expect("Bad permissions on /tmp/pika-installer-p3-size.txt");
|
2024-02-14 16:32:01 +01:00
|
|
|
}
|
2024-02-17 14:52:07 +01:00
|
|
|
let target_p3_sector = _target_p3_size + 1537.0;
|
2024-02-16 22:21:09 +01:00
|
|
|
fs::write(
|
|
|
|
"/tmp/pika-installer-p3-size.txt",
|
|
|
|
target_p3_sector.to_string(),
|
|
|
|
)
|
|
|
|
.expect("Unable to write file");
|
2024-02-17 14:52:07 +01:00
|
|
|
let mut _p1_row_text = String::new();
|
|
|
|
let mut _p2_row_text = String::new();
|
|
|
|
let mut _p3_row_text = String::new();
|
|
|
|
let mut _p4_row_text = String::new();
|
2024-02-14 16:32:01 +01:00
|
|
|
if target_block_device.contains("nvme") {
|
2024-02-17 14:52:07 +01:00
|
|
|
_p1_row_text =
|
2024-02-16 22:21:09 +01:00
|
|
|
"512 MB ".to_owned() + target_block_device + "p1" + " as fat32" + " on /boot/efi";
|
2024-02-17 14:52:07 +01:00
|
|
|
_p2_row_text =
|
2024-02-16 22:21:09 +01:00
|
|
|
"1 GB ".to_owned() + target_block_device + "p2" + " as ext4" + " on /boot";
|
2024-02-17 14:52:07 +01:00
|
|
|
_p3_row_text = pretty_bytes::converter::convert(_target_p3_size)
|
2024-02-16 22:21:09 +01:00
|
|
|
+ " "
|
|
|
|
+ target_block_device
|
|
|
|
+ "p3"
|
|
|
|
+ " as btrfs"
|
|
|
|
+ " on /";
|
2024-02-17 14:52:07 +01:00
|
|
|
_p4_row_text = pretty_bytes::converter::convert(target_p4_size)
|
2024-02-16 22:21:09 +01:00
|
|
|
+ " "
|
|
|
|
+ target_block_device
|
|
|
|
+ "p4"
|
|
|
|
+ " as btrfs"
|
|
|
|
+ " on /home";
|
2024-02-14 16:32:01 +01:00
|
|
|
} else {
|
2024-02-17 14:52:07 +01:00
|
|
|
_p1_row_text =
|
2024-02-16 22:21:09 +01:00
|
|
|
"512 MB ".to_owned() + target_block_device + "1" + " as fat32" + " on /boot/efi";
|
2024-02-19 18:44:10 +01:00
|
|
|
_p2_row_text =
|
|
|
|
"1 GB ".to_owned() + target_block_device + "2" + " as ext4" + " on /boot";
|
2024-02-17 14:52:07 +01:00
|
|
|
_p3_row_text = pretty_bytes::converter::convert(_target_p3_size)
|
2024-02-16 22:21:09 +01:00
|
|
|
+ " "
|
|
|
|
+ target_block_device
|
|
|
|
+ "3"
|
|
|
|
+ " as btrfs"
|
|
|
|
+ " on /";
|
2024-02-17 14:52:07 +01:00
|
|
|
_p4_row_text = pretty_bytes::converter::convert(target_p4_size)
|
2024-02-16 22:21:09 +01:00
|
|
|
+ " "
|
|
|
|
+ target_block_device
|
|
|
|
+ "4"
|
|
|
|
+ " as btrfs"
|
|
|
|
+ " on /home";
|
2024-02-14 16:32:01 +01:00
|
|
|
}
|
2024-02-19 18:44:10 +01:00
|
|
|
let install_confirm_p1 = adw::ActionRow::builder()
|
|
|
|
.title(_p1_row_text.clone())
|
|
|
|
.build();
|
|
|
|
let install_confirm_p2 = adw::ActionRow::builder()
|
|
|
|
.title(_p2_row_text.clone())
|
|
|
|
.build();
|
|
|
|
let install_confirm_p3 = adw::ActionRow::builder()
|
|
|
|
.title(_p3_row_text.clone())
|
|
|
|
.build();
|
|
|
|
let install_confirm_p4 = adw::ActionRow::builder()
|
|
|
|
.title(_p4_row_text.clone())
|
|
|
|
.build();
|
2024-02-14 16:32:01 +01:00
|
|
|
// / install_confirm_selection_box appends
|
|
|
|
//// add live and install media button to install page selections
|
|
|
|
install_confirm_details_boxed_list.append(&install_confirm_detail_language);
|
|
|
|
install_confirm_details_boxed_list.append(&install_confirm_detail_timezone);
|
|
|
|
install_confirm_details_boxed_list.append(&install_confirm_detail_keyboard);
|
|
|
|
install_confirm_details_boxed_list.append(&install_confirm_detail_target);
|
|
|
|
install_confirm_details_boxed_list.append(&install_confirm_p1);
|
|
|
|
install_confirm_details_boxed_list.append(&install_confirm_p2);
|
|
|
|
install_confirm_details_boxed_list.append(&install_confirm_p3);
|
|
|
|
install_confirm_details_boxed_list.append(&install_confirm_p4);
|
|
|
|
}
|
|
|
|
|
|
|
|
let install_confirm_button = gtk::Button::builder()
|
2024-02-20 16:11:38 +01:00
|
|
|
.label(t!("confirm_install_pika"))
|
2024-02-14 16:32:01 +01:00
|
|
|
.halign(gtk::Align::Center)
|
|
|
|
.valign(gtk::Align::Center)
|
|
|
|
.build();
|
|
|
|
install_confirm_button.add_css_class("destructive-action");
|
|
|
|
|
|
|
|
// / install_confirm_header_box appends
|
|
|
|
//// Add the install page header text and icon
|
|
|
|
install_confirm_header_box.append(&install_confirm_header_text);
|
|
|
|
install_confirm_header_box.append(&install_confirm_header_icon);
|
|
|
|
|
|
|
|
// / install_confirm_box appends
|
|
|
|
//// Add the install header to install main box
|
|
|
|
install_confirm_box.append(&install_confirm_header_box);
|
|
|
|
//// Add the install selection/page content box to install main box
|
|
|
|
install_confirm_box.append(&install_confirm_selection_box);
|
|
|
|
|
|
|
|
// Start Appending widgets to boxes
|
|
|
|
|
|
|
|
//
|
|
|
|
install_confirm_selection_box.append(&install_confirm_details_boxed_list);
|
|
|
|
install_confirm_selection_box.append(&install_confirm_button);
|
|
|
|
|
|
|
|
// / install_confirm_header_box appends
|
|
|
|
//// Add the install page header text and icon
|
|
|
|
install_confirm_header_box.append(&install_confirm_header_text);
|
|
|
|
install_confirm_header_box.append(&install_confirm_header_icon);
|
|
|
|
|
|
|
|
// / install_confirm_box appends
|
|
|
|
//// Add the install header to install main box
|
|
|
|
install_confirm_box.append(&install_confirm_header_box);
|
|
|
|
//// Add the install selection/page content box to install main box
|
|
|
|
install_confirm_box.append(&install_confirm_selection_box);
|
|
|
|
|
|
|
|
install_main_box.append(&install_nested_stack);
|
|
|
|
|
|
|
|
install_confirm_box.append(&bottom_box);
|
|
|
|
|
|
|
|
let install_progress_box = gtk::Box::builder()
|
|
|
|
.orientation(Orientation::Vertical)
|
|
|
|
.build();
|
|
|
|
|
|
|
|
let install_progress_log_stack = gtk::Stack::builder()
|
|
|
|
.transition_type(StackTransitionType::SlideUpDown)
|
|
|
|
.build();
|
|
|
|
|
|
|
|
let install_progress_log_terminal = vte::Terminal::builder()
|
|
|
|
.vexpand(true)
|
|
|
|
.hexpand(true)
|
|
|
|
.margin_top(15)
|
|
|
|
.margin_bottom(15)
|
|
|
|
.margin_start(15)
|
|
|
|
.margin_end(15)
|
|
|
|
.input_enabled(false)
|
|
|
|
.build();
|
|
|
|
|
|
|
|
let placeholder_icon = gtk::Image::builder()
|
2024-02-18 16:39:04 +01:00
|
|
|
.icon_name(DISTRO_ICON)
|
2024-02-14 16:32:01 +01:00
|
|
|
.halign(gtk::Align::Center)
|
|
|
|
.valign(gtk::Align::Center)
|
|
|
|
.hexpand(true)
|
|
|
|
.vexpand(true)
|
|
|
|
.pixel_size(512)
|
|
|
|
.margin_top(15)
|
|
|
|
.margin_bottom(15)
|
|
|
|
.margin_start(15)
|
|
|
|
.margin_end(15)
|
|
|
|
.build();
|
|
|
|
|
|
|
|
let progress_bar_box = gtk::Box::builder()
|
|
|
|
.orientation(Orientation::Horizontal)
|
|
|
|
.margin_start(15)
|
|
|
|
.margin_end(15)
|
|
|
|
.build();
|
|
|
|
|
|
|
|
let install_progress_bar = gtk::ProgressBar::builder()
|
|
|
|
.hexpand(true)
|
|
|
|
.margin_start(15)
|
|
|
|
.margin_end(15)
|
|
|
|
.margin_top(15)
|
|
|
|
.margin_bottom(15)
|
|
|
|
.show_text(true)
|
|
|
|
.build();
|
2024-02-20 16:11:38 +01:00
|
|
|
install_progress_bar.add_css_class("small_fg_text");
|
2024-02-14 16:32:01 +01:00
|
|
|
|
|
|
|
let progress_log_button_content = adw::ButtonContent::builder()
|
2024-02-20 16:11:38 +01:00
|
|
|
.label(t!("view_logs"))
|
2024-02-14 16:32:01 +01:00
|
|
|
.icon_name("terminal")
|
|
|
|
.build();
|
|
|
|
|
|
|
|
let progress_log_button = gtk::Button::builder()
|
|
|
|
.child(&progress_log_button_content)
|
|
|
|
.margin_start(15)
|
|
|
|
.margin_end(15)
|
|
|
|
.margin_top(15)
|
|
|
|
.margin_bottom(15)
|
|
|
|
.build();
|
|
|
|
|
|
|
|
progress_bar_box.append(&install_progress_bar);
|
|
|
|
progress_bar_box.append(&progress_log_button);
|
|
|
|
|
2024-02-16 22:21:09 +01:00
|
|
|
install_progress_log_stack.add_titled(
|
|
|
|
&placeholder_icon,
|
|
|
|
Some("slideshow_page"),
|
|
|
|
"slideshow_page",
|
|
|
|
);
|
|
|
|
install_progress_log_stack.add_titled(
|
|
|
|
&install_progress_log_terminal,
|
|
|
|
Some("terminal_log_page"),
|
|
|
|
"terminal_log_page",
|
|
|
|
);
|
2024-02-14 16:32:01 +01:00
|
|
|
|
|
|
|
install_progress_box.append(&install_progress_log_stack);
|
|
|
|
install_progress_box.append(&progress_bar_box);
|
|
|
|
|
|
|
|
install_nested_stack.add_titled(&install_confirm_box, Some("confirm_page"), "confirm_page");
|
2024-02-16 22:21:09 +01:00
|
|
|
install_nested_stack.add_titled(
|
|
|
|
&install_progress_box,
|
|
|
|
Some("progress_page"),
|
|
|
|
"progress_page",
|
|
|
|
);
|
2024-02-14 16:32:01 +01:00
|
|
|
|
|
|
|
//
|
|
|
|
|
|
|
|
//
|
|
|
|
|
|
|
|
install_confirm_button.connect_clicked(clone!(@weak install_nested_stack, @weak install_progress_log_terminal, @weak install_progress_bar, @weak done_main_box, @weak content_stack, @weak window => move |_| {
|
|
|
|
install_nested_stack.set_visible_child_name("progress_page");
|
|
|
|
begin_install(&install_progress_log_terminal, &install_progress_bar, &done_main_box, &content_stack, &window);
|
|
|
|
}));
|
|
|
|
|
|
|
|
progress_log_button.connect_clicked(clone!(@weak install_progress_log_stack => move |_| {
|
|
|
|
if install_progress_log_stack.visible_child_name() == Some(GString::from_string_unchecked("slideshow_page".into())) {
|
|
|
|
install_progress_log_stack.set_visible_child_name("terminal_log_page");
|
|
|
|
} else {
|
|
|
|
install_progress_log_stack.set_visible_child_name("slideshow_page");
|
|
|
|
}
|
|
|
|
}));
|
|
|
|
|
2024-02-16 22:21:09 +01:00
|
|
|
bottom_back_button.connect_clicked(
|
|
|
|
clone!(@weak content_stack, @weak install_main_box, @weak install_nested_stack => move |_| {
|
|
|
|
content_stack.set_visible_child_name("partitioning_page");
|
|
|
|
install_main_box.remove(&install_nested_stack)
|
|
|
|
}),
|
|
|
|
);
|
2024-02-14 16:32:01 +01:00
|
|
|
}
|
|
|
|
|
2024-02-16 22:21:09 +01:00
|
|
|
fn begin_install(
|
|
|
|
install_progress_log_terminal: &vte::Terminal,
|
|
|
|
install_progress_bar: >k::ProgressBar,
|
|
|
|
done_main_box: >k::Box,
|
|
|
|
content_stack: >k::Stack,
|
|
|
|
window: &adw::ApplicationWindow,
|
|
|
|
) {
|
2024-02-14 16:32:01 +01:00
|
|
|
// SPAWN TERMINAL WITH PIKAINSTALL PROCESS
|
|
|
|
install_progress_log_terminal.spawn_async(
|
|
|
|
PtyFlags::DEFAULT,
|
|
|
|
Some(""),
|
|
|
|
&["/usr/lib/pika/pika-installer-gtk4/scripts/begin-install.sh"],
|
|
|
|
&[],
|
|
|
|
SpawnFlags::DEFAULT,
|
|
|
|
|| {},
|
|
|
|
-1,
|
|
|
|
None::<&gio::Cancellable>,
|
2024-02-16 22:21:09 +01:00
|
|
|
move |result| match result {
|
|
|
|
Ok(_) => {
|
|
|
|
eprintln!("could not spawn terminal")
|
|
|
|
}
|
|
|
|
Err(err) => {
|
|
|
|
eprintln!("could not spawn terminal: {}", err);
|
2024-02-14 16:32:01 +01:00
|
|
|
}
|
|
|
|
},
|
|
|
|
);
|
|
|
|
// wait till /tmp/pika-installer-gtk4-status-parting.txt to change progressbar
|
|
|
|
let (parting_status_sender, parting_status_receiver) = async_channel::unbounded();
|
|
|
|
let parting_status_sender = parting_status_sender.clone();
|
|
|
|
// The long running operation runs now in a separate thread
|
|
|
|
gio::spawn_blocking(move || {
|
|
|
|
let parting_status = true;
|
|
|
|
while parting_status == true {
|
|
|
|
if Path::new("/tmp/pika-installer-gtk4-status-parting.txt").exists() == true {
|
|
|
|
parting_status_sender
|
|
|
|
.send_blocking(true)
|
|
|
|
.expect("The channel needs to be open.");
|
2024-02-16 22:21:09 +01:00
|
|
|
break;
|
2024-02-14 16:32:01 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
let parting_status_main_context = MainContext::default();
|
|
|
|
// The main loop executes the asynchronous block
|
|
|
|
parting_status_main_context.spawn_local(clone!(@weak install_progress_bar => async move {
|
|
|
|
while let Ok(parting_status_state) = parting_status_receiver.recv().await {
|
|
|
|
|
|
|
|
if parting_status_state == true {
|
|
|
|
println!("Installation status: Parting");
|
|
|
|
install_progress_bar.set_fraction(0.20);
|
2024-02-20 16:11:38 +01:00
|
|
|
install_progress_bar.set_text(Some(&t!("parting_status_text")));
|
2024-02-14 16:32:01 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}));
|
|
|
|
// wait till /tmp/pika-installer-gtk4-status-image.txt to change progressbar
|
|
|
|
let (image_status_sender, image_status_receiver) = async_channel::unbounded();
|
|
|
|
let image_status_sender = image_status_sender.clone();
|
|
|
|
// The long running operation runs now in a separate thread
|
|
|
|
gio::spawn_blocking(move || {
|
|
|
|
let image_status = true;
|
|
|
|
while image_status == true {
|
|
|
|
if Path::new("/tmp/pika-installer-gtk4-status-image.txt").exists() == true {
|
|
|
|
image_status_sender
|
|
|
|
.send_blocking(true)
|
|
|
|
.expect("The channel needs to be open.");
|
2024-02-16 22:21:09 +01:00
|
|
|
break;
|
2024-02-14 16:32:01 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
let image_status_main_context = MainContext::default();
|
|
|
|
// The main loop executes the asynchronous block
|
|
|
|
image_status_main_context.spawn_local(clone!(@weak install_progress_bar => async move {
|
|
|
|
while let Ok(image_status_state) = image_status_receiver.recv().await {
|
|
|
|
|
|
|
|
if image_status_state == true {
|
|
|
|
println!("Installation status: Imaging");
|
|
|
|
install_progress_bar.set_fraction(0.60);
|
2024-02-20 16:11:38 +01:00
|
|
|
install_progress_bar.set_text(Some(&t!("image_status_text")));
|
2024-02-14 16:32:01 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}));
|
|
|
|
// wait till /tmp/pika-installer-gtk4-status-flag1.txt to change progressbar
|
|
|
|
let (flag1_status_sender, flag1_status_receiver) = async_channel::unbounded();
|
|
|
|
let flag1_status_sender = flag1_status_sender.clone();
|
|
|
|
// The long running operation runs now in a separate thread
|
|
|
|
gio::spawn_blocking(move || {
|
|
|
|
let flag1_status = true;
|
|
|
|
while flag1_status == true {
|
|
|
|
if Path::new("/tmp/pika-installer-gtk4-status-flag1.txt").exists() == true {
|
|
|
|
flag1_status_sender
|
|
|
|
.send_blocking(true)
|
|
|
|
.expect("The channel needs to be open.");
|
2024-02-16 22:21:09 +01:00
|
|
|
break;
|
2024-02-14 16:32:01 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
let flag1_status_main_context = MainContext::default();
|
|
|
|
// The main loop executes the asynchronous block
|
|
|
|
flag1_status_main_context.spawn_local(clone!(@weak install_progress_bar => async move {
|
|
|
|
while let Ok(flag1_status_state) = flag1_status_receiver.recv().await {
|
|
|
|
|
|
|
|
if flag1_status_state == true {
|
|
|
|
println!("Installation status: Flag1");
|
|
|
|
install_progress_bar.set_fraction(0.65);
|
2024-02-20 16:11:38 +01:00
|
|
|
install_progress_bar.set_text(Some(&t!("flag1_status_text")));
|
2024-02-14 16:32:01 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}));
|
|
|
|
// wait till /tmp/pika-installer-gtk4-status-flag2.txt to change progressbar
|
|
|
|
let (flag2_status_sender, flag2_status_receiver) = async_channel::unbounded();
|
|
|
|
let flag2_status_sender = flag2_status_sender.clone();
|
|
|
|
// The long running operation runs now in a separate thread
|
|
|
|
gio::spawn_blocking(move || {
|
|
|
|
let flag2_status = true;
|
|
|
|
while flag2_status == true {
|
|
|
|
if Path::new("/tmp/pika-installer-gtk4-status-flag2.txt").exists() == true {
|
|
|
|
flag2_status_sender
|
|
|
|
.send_blocking(true)
|
|
|
|
.expect("The channel needs to be open.");
|
2024-02-16 22:21:09 +01:00
|
|
|
break;
|
2024-02-14 16:32:01 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
let flag2_status_main_context = MainContext::default();
|
|
|
|
// The main loop executes the asynchronous block
|
|
|
|
flag2_status_main_context.spawn_local(clone!(@weak install_progress_bar => async move {
|
|
|
|
while let Ok(flag2_status_state) = flag2_status_receiver.recv().await {
|
|
|
|
|
|
|
|
if flag2_status_state == true {
|
|
|
|
println!("Installation status: Flag2");
|
|
|
|
install_progress_bar.set_fraction(0.70);
|
2024-02-20 16:11:38 +01:00
|
|
|
install_progress_bar.set_text(Some(&t!("flag2_status_text")));
|
2024-02-14 16:32:01 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}));
|
|
|
|
// wait till /tmp/pika-installer-gtk4-status-crypt.txt to change progressbar
|
|
|
|
let (crypt_status_sender, crypt_status_receiver) = async_channel::unbounded();
|
|
|
|
let crypt_status_sender = crypt_status_sender.clone();
|
|
|
|
// The long running operation runs now in a separate thread
|
|
|
|
gio::spawn_blocking(move || {
|
|
|
|
let crypt_status = true;
|
|
|
|
while crypt_status == true {
|
|
|
|
if Path::new("/tmp/pika-installer-gtk4-status-crypt.txt").exists() == true {
|
|
|
|
crypt_status_sender
|
|
|
|
.send_blocking(true)
|
|
|
|
.expect("The channel needs to be open.");
|
2024-02-16 22:21:09 +01:00
|
|
|
break;
|
2024-02-14 16:32:01 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
let crypt_status_main_context = MainContext::default();
|
|
|
|
// The main loop executes the asynchronous block
|
|
|
|
crypt_status_main_context.spawn_local(clone!(@weak install_progress_bar => async move {
|
|
|
|
while let Ok(crypt_status_state) = crypt_status_receiver.recv().await {
|
|
|
|
|
|
|
|
if crypt_status_state == true {
|
|
|
|
println!("Installation status: Crypttab");
|
|
|
|
install_progress_bar.set_fraction(0.75);
|
2024-02-20 16:11:38 +01:00
|
|
|
install_progress_bar.set_text(Some(&t!("crypt_status_text")));
|
2024-02-14 16:32:01 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}));
|
|
|
|
// wait till /tmp/pika-installer-gtk4-status-lang.txt to change progressbar
|
|
|
|
let (lang_status_sender, lang_status_receiver) = async_channel::unbounded();
|
|
|
|
let lang_status_sender = lang_status_sender.clone();
|
|
|
|
// The long running operation runs now in a separate thread
|
|
|
|
gio::spawn_blocking(move || {
|
|
|
|
let lang_status = true;
|
|
|
|
while lang_status == true {
|
|
|
|
if Path::new("/tmp/pika-installer-gtk4-status-lang.txt").exists() == true {
|
|
|
|
lang_status_sender
|
|
|
|
.send_blocking(true)
|
|
|
|
.expect("The channel needs to be open.");
|
2024-02-16 22:21:09 +01:00
|
|
|
break;
|
2024-02-14 16:32:01 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
let lang_status_main_context = MainContext::default();
|
|
|
|
// The main loop executes the asynchronous block
|
|
|
|
lang_status_main_context.spawn_local(clone!(@weak install_progress_bar => async move {
|
|
|
|
while let Ok(lang_status_state) = lang_status_receiver.recv().await {
|
|
|
|
|
|
|
|
if lang_status_state == true {
|
|
|
|
println!("Installation status: Language");
|
|
|
|
install_progress_bar.set_fraction(0.80);
|
2024-02-20 16:11:38 +01:00
|
|
|
install_progress_bar.set_text(Some(&t!("lang_status_text")));
|
2024-02-14 16:32:01 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}));
|
|
|
|
// wait till /tmp/pika-installer-gtk4-status-boot.txt to change progressbar
|
|
|
|
let (boot_status_sender, boot_status_receiver) = async_channel::unbounded();
|
|
|
|
let boot_status_sender = boot_status_sender.clone();
|
|
|
|
// The long running operation runs now in a separate thread
|
|
|
|
gio::spawn_blocking(move || {
|
|
|
|
let boot_status = true;
|
|
|
|
while boot_status == true {
|
|
|
|
if Path::new("/tmp/pika-installer-gtk4-status-boot.txt").exists() == true {
|
|
|
|
boot_status_sender
|
|
|
|
.send_blocking(true)
|
|
|
|
.expect("The channel needs to be open.");
|
2024-02-16 22:21:09 +01:00
|
|
|
break;
|
2024-02-14 16:32:01 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
let boot_status_main_context = MainContext::default();
|
|
|
|
// The main loop executes the asynchronous block
|
|
|
|
boot_status_main_context.spawn_local(clone!(@weak install_progress_bar => async move {
|
|
|
|
while let Ok(boot_status_state) = boot_status_receiver.recv().await {
|
|
|
|
|
|
|
|
if boot_status_state == true {
|
|
|
|
println!("Installation status: Bootloader");
|
|
|
|
install_progress_bar.set_fraction(0.85);
|
2024-02-20 16:11:38 +01:00
|
|
|
install_progress_bar.set_text(Some(&t!("boot_status_status_text")));
|
2024-02-14 16:32:01 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}));
|
|
|
|
// wait till /tmp/pika-installer-gtk4-status-post.txt to change progressbar
|
|
|
|
let (post_status_sender, post_status_receiver) = async_channel::unbounded();
|
|
|
|
let post_status_sender = post_status_sender.clone();
|
|
|
|
// The long running operation runs now in a separate thread
|
|
|
|
gio::spawn_blocking(move || {
|
|
|
|
let post_status = true;
|
|
|
|
while post_status == true {
|
|
|
|
if Path::new("/tmp/pika-installer-gtk4-status-post.txt").exists() == true {
|
|
|
|
post_status_sender
|
|
|
|
.send_blocking(true)
|
|
|
|
.expect("The channel needs to be open.");
|
2024-02-16 22:21:09 +01:00
|
|
|
break;
|
2024-02-14 16:32:01 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
let post_status_main_context = MainContext::default();
|
|
|
|
// The main loop executes the asynchronous block
|
|
|
|
post_status_main_context.spawn_local(clone!(@weak install_progress_bar => async move {
|
|
|
|
while let Ok(post_status_state) = post_status_receiver.recv().await {
|
|
|
|
|
|
|
|
if post_status_state == true {
|
|
|
|
println!("Installation status: Post Install");
|
|
|
|
install_progress_bar.set_fraction(0.90);
|
2024-02-20 16:11:38 +01:00
|
|
|
install_progress_bar.set_text(Some(&t!("post_status_text")));
|
2024-02-14 16:32:01 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}));
|
|
|
|
// wait till /tmp/pika-installer-gtk4-successful.txt to change progressbar
|
|
|
|
let (done_status_sender, done_status_receiver) = async_channel::unbounded();
|
|
|
|
let done_status_sender = done_status_sender.clone();
|
|
|
|
// The long running operation runs now in a separate thread
|
|
|
|
gio::spawn_blocking(move || {
|
|
|
|
let done_status = true;
|
|
|
|
while done_status == true {
|
2024-02-16 22:21:09 +01:00
|
|
|
if Path::new("/tmp/pika-installer-gtk4-successful.txt").exists() == true
|
|
|
|
|| Path::new("/tmp/pika-installer-gtk4-fail.txt").exists() == true
|
|
|
|
{
|
2024-02-14 16:32:01 +01:00
|
|
|
done_status_sender
|
|
|
|
.send_blocking(true)
|
|
|
|
.expect("The channel needs to be open.");
|
2024-02-16 22:21:09 +01:00
|
|
|
break;
|
2024-02-14 16:32:01 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
let done_status_main_context = MainContext::default();
|
|
|
|
// The main loop executes the asynchronous block
|
2024-02-16 22:21:09 +01:00
|
|
|
done_status_main_context.spawn_local(
|
|
|
|
clone!(@weak done_main_box, @weak content_stack, @weak window => async move {
|
|
|
|
while let Ok(done_status_state) = done_status_receiver.recv().await {
|
|
|
|
if done_status_state == true {
|
|
|
|
println!("Installation status: Done");
|
2024-02-17 14:52:07 +01:00
|
|
|
done_page(&done_main_box, &window);
|
2024-02-16 22:21:09 +01:00
|
|
|
content_stack.set_visible_child_name("done_page");
|
|
|
|
}
|
2024-02-14 16:32:01 +01:00
|
|
|
}
|
2024-02-16 22:21:09 +01:00
|
|
|
}),
|
|
|
|
);
|
|
|
|
}
|