// SPDX-License-Identifier: EUPL-1.2+ // SPDX-FileCopyrightText: 2025 Johannes Süllner use super::{BUTTON_TEXT_SIZE, Event, MARGIN_VERTICAL, Page, TITLE_TEXT_SIZE, UpdateResult}; use crate::{center_horizontal_in_container, center_in_container}; use iced::{ Element, Task, widget::{column, qr_code, space, text}, window, }; use std::process::Command; const S6_HPR_PATH: &str = "/bin/s6-linux-init-hpr"; const QR_CODE_SIZE: u32 = 350; const MAX_QR_CODE_LOG_LENGTH: usize = 2000; // The QR code can't contain much more data. pub struct PageCompletion { install_result: super::InstallResult, qr_data_result: Option>, } impl PageCompletion { pub fn new(install_result: super::InstallResult) -> Self { let qr_data_result = match install_result.clone() { Ok(_) => None, Err((code, log)) => { let log_len = log.len(); Some(qr_code::Data::new( format!( "Error code: {}\nLog:\n{}", code, if log_len > MAX_QR_CODE_LOG_LENGTH { &log[(log_len - MAX_QR_CODE_LOG_LENGTH)..] } else { &log } ) .as_bytes(), )) } }; Self { install_result, qr_data_result, } } } #[derive(Clone, Debug)] pub enum PageCompletionEvent { Quit, Poweroff, Reboot, } impl PageCompletion { fn spawn_s6_hpr(parameter: &str) { let _ = Command::new(S6_HPR_PATH).arg(parameter).spawn(); } } impl Page for PageCompletion { fn update(&mut self, event: Event) -> UpdateResult { if let Event::PageCompletion(page_completion_event) = event { match page_completion_event { PageCompletionEvent::Quit => { return (None, window::latest().and_then(window::close)); } PageCompletionEvent::Poweroff => { Self::spawn_s6_hpr("-p"); } PageCompletionEvent::Reboot => { Self::spawn_s6_hpr("-r"); } } }; (None, Task::none()) } fn view(&self) -> Element<'_, Event> { let main_element = match &self.install_result { Ok(_) => { center_in_container!(text("Spectrum installation succeeded!").size(TITLE_TEXT_SIZE)) .into() } Err(_) => { let mut widgets = column![ space().height(MARGIN_VERTICAL), center_horizontal_in_container!( text("Spectrum installation failed :(").size(TITLE_TEXT_SIZE) ), space().height(MARGIN_VERTICAL), center_horizontal_in_container!(text(format!( "You can reach out to the team via Chat or the public mailing list\n\ (discuss@spectrum-os.org).\n\ See https://spectrum-os.org/doc/contributing/communication.html for details.\n\ Scan the QR code to obtain the install log." ))), ]; widgets = if let Some(Ok(qr_data)) = &self.qr_data_result { widgets.push(center_in_container!( qr_code(&qr_data).total_size(QR_CODE_SIZE) )) } else { widgets.push(center_horizontal_in_container!(text( "Error encoding QR code." ))) }; widgets.into() } }; super::layout::bottom_buttons_layout( [ vec![ ( text("Reboot").size(BUTTON_TEXT_SIZE).into(), Some(Event::PageCompletion(PageCompletionEvent::Reboot)), ), ( text("Poweroff").size(BUTTON_TEXT_SIZE).into(), Some(Event::PageCompletion(PageCompletionEvent::Poweroff)), ), ], vec![( text("Quit installer, stay in live environment") .size(BUTTON_TEXT_SIZE) .into(), Some(Event::PageCompletion(PageCompletionEvent::Quit)), )], ], main_element, ) } }