From 91acde5317251d9b27c330adcf93929387b506c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Erkan=20I=C5=9EIK?= Date: Sat, 22 Aug 2026 13:09:04 +0300 Subject: [PATCH] =?UTF-8?q?fix:=20manuel=20ve=20otomatik=20b=C3=B6l=C3=BCm?= =?UTF-8?q?lemede=20k=C3=B6k=20dizin=20boyutu=20hesaplama=20hatas=C4=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/autoinstall/checker.rs | 2 +- src/autoinstall/mod.rs | 4 +- src/steps/execution.rs | 241 ++++++++++++++++++------------------- src/steps/partition.rs | 27 +++-- src/ui/slideshow.rs | 38 +----- 5 files changed, 139 insertions(+), 173 deletions(-) diff --git a/src/autoinstall/checker.rs b/src/autoinstall/checker.rs index 116d06e..5219eea 100644 --- a/src/autoinstall/checker.rs +++ b/src/autoinstall/checker.rs @@ -63,7 +63,7 @@ pub fn all_passed(results: &[CheckResult]) -> bool { fn check_ram() -> CheckResult { let mut sys = System::new(); sys.refresh_memory(); - let mb = sys.total_memory() / 1024 / 1024; + let mb = sys.total_memory() / 1_048_576; if mb < 1024 { CheckResult::fail( diff --git a/src/autoinstall/mod.rs b/src/autoinstall/mod.rs index 6378ebe..86c1b5d 100644 --- a/src/autoinstall/mod.rs +++ b/src/autoinstall/mod.rs @@ -137,12 +137,12 @@ pub fn apply_to_state(af: &AnswerFile, state: &mut crate::installer::GlobalState if let Some(info) = disk_info { let is_uefi = std::path::Path::new("/sys/firmware/efi").exists(); let efi_mb = if is_uefi { 512u64 } else { 0 }; - let total_mb = info.size_bytes / 1024 / 1024; + let total_mb = info.size_bytes / 1_048_576; // Swap: RAM * 1.0, min 512 MB, max 2048 MB, ayrıca diskin %10'unu geçmesin let mut sys = sysinfo::System::new(); sys.refresh_memory(); - let ram_mb = sys.total_memory() / 1024 / 1024; + let ram_mb = sys.total_memory() / 1_048_576; let disk_10pct = total_mb / 10; let swap_mb = ram_mb.clamp(512, 2048).min(disk_10pct); diff --git a/src/steps/execution.rs b/src/steps/execution.rs index d7031d2..5d083da 100644 --- a/src/steps/execution.rs +++ b/src/steps/execution.rs @@ -7,6 +7,7 @@ use std::sync::mpsc; use std::thread; +use std::time::{Duration, Instant}; use eframe::egui; use rust_i18n::t; @@ -24,6 +25,8 @@ pub struct ExecutionStep { slideshow: Option, /// rsync kopyalama fazı aktifken tek ilerleme çubuğu gösterilir. copy_active: bool, + /// Kurulum bitince tamamlandı ekranına otomatik geçiş için zaman damgası. + finished_at: Option, } impl InstallerStep for ExecutionStep { @@ -35,6 +38,7 @@ impl InstallerStep for ExecutionStep { self.tx = Some(tx); self.finished = false; self.error_screen = None; + self.finished_at = None; let desktop = std::env::var("XDG_CURRENT_DESKTOP") .unwrap_or_else(|_| "default".to_string()) @@ -206,6 +210,7 @@ impl InstallerStep for ExecutionStep { Ok(InstallMessage::Done) => { state.install_progress = 1.0; self.finished = true; + self.finished_at = Some(Instant::now()); } Ok(InstallMessage::Error(e)) => { self.error_screen = Some(ErrorScreen::new( @@ -240,134 +245,108 @@ impl InstallerStep for ExecutionStep { } // ── Normal kurulum görünümü ──────────────────────────── - // Üst: Slayt gösterisi | Alt: ilerleme + log + // Üst: Slayt gösterisi (kalan alanı doldurur) | Alt: ilerleme durumu let available_w = ui.available_width(); - let available_h = ui.available_height(); ui.vertical(|ui| { - // Üst kısım — slayt gösterisi - let slide_h = (available_h * 0.45).max(280.0); - ui.allocate_ui(egui::vec2(available_w, slide_h), |ui| { - ui.vertical(|ui| { - ui.add_space(8.0); - theme::section_heading(ui, &t!("execution_title")); - ui.label( - egui::RichText::new(t!("execution_description")) - .color(theme::c_text_dim()) - .size(13.0), - ); - ui.add_space(16.0); + // ── Üst kısım — başlık + slayt gösterisi (kalan alanı doldurur) ── + ui.add_space(8.0); + theme::section_heading(ui, &t!("execution_title")); + ui.label( + egui::RichText::new(t!("execution_description")) + .color(theme::c_text_dim()) + .size(13.0), + ); + ui.add_space(16.0); - if let Some(ref mut ss) = self.slideshow { - ss.show(ui); - ui.add_space(10.0); - // Manuel ileri/geri butonları - ui.horizontal(|ui| { - if ui.small_button("‹").clicked() { ss.previous(); } - if ui.small_button("›").clicked() { ss.advance(); } - }); - } - }); + // Alt kısım (ilerleme + durum) için ayrılan yükseklik. + // bottom_up layout en sonda olduğu için slayt alanını kalan + // yükseklikle sınırlandırıyoruz; aksi halde slayt gösterisi + // ekranın dışına itilir. + let bottom_h = 170.0; + let slide_h = (ui.available_height() - bottom_h).max(200.0); + ui.allocate_ui(egui::vec2(available_w, slide_h), |ui| { + ui.set_min_height(slide_h); + if let Some(ref mut ss) = self.slideshow { + ss.show(ui); + } }); - ui.add_space(16.0); - ui.separator(); ui.add_space(16.0); - // Alt kısım — ilerleme + log - let log_h = available_h - slide_h - 50.0; - ui.allocate_ui(egui::vec2(available_w, log_h), |ui| { - ui.vertical(|ui| { - ui.add_space(8.0); + // ── Alt kısım — ilerleme + durum (en altta) ────────── + ui.with_layout(egui::Layout::bottom_up(egui::Align::Min), |ui| { + ui.add_space(8.0); - // İlerleme çubuğu — yalnızca rsync kopyalama fazında - // tek bar gösterilir (eski YALI düzeni). Diğer adımlar - // (fstab, GRUB, temizlik vb.) metin + spinner olarak - // görünür. - let running = !self.finished - && self.error_screen.is_none() - && (self.copy_active || state.install_progress > 0.0); + // İlerleme çubuğu — yalnızca rsync kopyalama fazında + // tek bar gösterilir (eski YALI düzeni). Diğer adımlar + // (fstab, GRUB, temizlik vb.) metin + spinner olarak + // görünür. + let running = !self.finished + && self.error_screen.is_none() + && (self.copy_active || state.install_progress > 0.0); - egui::Frame::none() - .fill(theme::c_bg_widget()) - .rounding(egui::Rounding::same(8.0)) - .inner_margin(egui::Margin::same(12.0)) - .show(ui, |ui| { - ui.set_width(available_w - 4.0); - let step_label = state.install_log.last() - .cloned() - .unwrap_or_default(); - ui.label( - egui::RichText::new(&step_label) - .size(12.0) - .color(theme::c_text_dim()), + egui::Frame::none() + .fill(theme::c_bg_widget()) + .rounding(egui::Rounding::same(8.0)) + .inner_margin(egui::Margin::same(12.0)) + .show(ui, |ui| { + ui.set_width(available_w - 4.0); + let step_label = state.install_log.last() + .cloned() + .unwrap_or_default(); + ui.label( + egui::RichText::new(&step_label) + .size(12.0) + .color(theme::c_text_dim()), + ); + + if self.copy_active { + let pct = format!("{:.0}%", state.install_sub_progress * 100.0); + let bar = ui.add( + egui::ProgressBar::new(state.install_sub_progress) + .animate(running) + .desired_height(20.0), + ); + ui.painter().text( + bar.rect.center(), + egui::Align2::CENTER_CENTER, + pct, + egui::FontId::proportional(14.0), + theme::c_text(), ); - if self.copy_active { - let pct = format!("{:.0}%", state.install_sub_progress * 100.0); - let bar = ui.add( - egui::ProgressBar::new(state.install_sub_progress) - .animate(running) - .desired_height(20.0), - ); - ui.painter().text( - bar.rect.center(), - egui::Align2::CENTER_CENTER, - pct, - egui::FontId::proportional(14.0), - theme::c_text(), - ); - - if let Some(ref current_file) = state.install_current_file { - ui.add_space(4.0); - ui.label( - egui::RichText::new(format!("{}: {}", t!("install_current_file"), current_file)) - .size(12.0) - .color(theme::c_text_dim()), - ); - } - } else if running { + if let Some(ref current_file) = state.install_current_file { ui.add_space(4.0); - ui.horizontal(|ui| { - ui.spinner(); - ui.colored_label(theme::c_text_dim(), t!("install_in_progress")); - }); + ui.label( + egui::RichText::new(format!("{}: {}", t!("install_current_file"), current_file)) + .size(12.0) + .color(theme::c_text_dim()), + ); } - }); + } else if running { + ui.add_space(4.0); + ui.horizontal(|ui| { + ui.spinner(); + ui.colored_label(theme::c_text_dim(), t!("install_in_progress")); + }); + } + }); - // Durum etiketi - ui.add_space(8.0); - if self.finished { - theme::success_box(ui, &t!("install_done")); - } else if running { - ui.horizontal(|ui| { - ui.spinner(); - ui.colored_label(theme::c_text_dim(), t!("install_in_progress")); - }); - } + // Durum etiketi + ui.add_space(8.0); + if self.finished { + theme::success_box(ui, &t!("install_done")); + } else if running { + ui.horizontal(|ui| { + ui.spinner(); + ui.colored_label(theme::c_text_dim(), t!("install_in_progress")); + }); + } - ui.add_space(8.0); - - // Log terminali - let terminal_h = if self.finished { log_h - 60.0 } else { log_h - 80.0 }; - egui::ScrollArea::vertical() - .max_height(terminal_h.max(100.0)) - .stick_to_bottom(true) - .id_source("exec_log") - .show(ui, |ui| { - egui::Frame::none() - .fill(egui::Color32::from_rgb(12, 12, 20)) - .rounding(egui::Rounding::same(6.0)) - .inner_margin(egui::Margin::same(10.0)) - .show(ui, |ui| { - ui.set_width(available_w - 8.0); - for line in &state.install_log { - let color = log_color(line); - ui.colored_label(color, line); - } - }); - }); - }); + ui.add_space(16.0); + ui.separator(); + ui.add_space(16.0); }); }); @@ -375,6 +354,18 @@ impl InstallerStep for ExecutionStep { if !self.finished && self.error_screen.is_none() { ui.ctx().request_repaint(); } + + // Kurulum tamamlanınca kısa bir bekleyişten sonra otomatik olarak + // tamamlandı ekranına geç + if self.finished && self.error_screen.is_none() { + if let Some(at) = self.finished_at { + if at.elapsed() >= Duration::from_secs(2) { + state.current_step += 1; + } else { + ui.ctx().request_repaint_after(Duration::from_secs(1)); + } + } + } } fn is_complete(&self, _state: &GlobalState) -> bool { @@ -382,16 +373,16 @@ impl InstallerStep for ExecutionStep { } } -fn log_color(line: &str) -> egui::Color32 { - if line.starts_with('✗') { - theme::c_error() - } else if line.starts_with('✓') { - theme::c_success() - } else if line.starts_with('▶') { - theme::c_accent() - } else if line.starts_with('⚠') { - theme::c_warning() - } else { - egui::Color32::from_rgb(185, 185, 205) - } -} +// fn log_color(line: &str) -> egui::Color32 { +// if line.starts_with('✗') { +// theme::c_error() +// } else if line.starts_with('✓') { +// theme::c_success() +// } else if line.starts_with('▶') { +// theme::c_accent() +// } else if line.starts_with('⚠') { +// theme::c_warning() +// } else { +// egui::Color32::from_rgb(185, 185, 205) +// } +// } diff --git a/src/steps/partition.rs b/src/steps/partition.rs index a061c44..efd46c7 100644 --- a/src/steps/partition.rs +++ b/src/steps/partition.rs @@ -296,7 +296,7 @@ fn recommended_swap_mb() -> u64 { use sysinfo::System; let mut sys = System::new(); sys.refresh_memory(); - let ram_mb = sys.total_memory() / 1024 / 1024; + let ram_mb = sys.total_memory() / 1_048_576; let swap = if ram_mb <= 2048 { ram_mb } else if ram_mb <= 8192 { @@ -312,7 +312,7 @@ fn make_plan(disk: &DiskInfo, is_uefi: bool) -> Option { if disk.size_gb < MIN_DISK_GB { return None; } - let total_mb = disk.size_bytes / 1024 / 1024; + let total_mb = disk.size_bytes / 1_048_576; let efi_mb = if is_uefi { EFI_MB } else { 0 }; let swap_mb = recommended_swap_mb(); let overhead = efi_mb + swap_mb + 512; @@ -489,7 +489,8 @@ impl PartitionStep { if response.clicked() && !too_small { state.selected_disk = Some(disk.name.clone()); - self.selected_disk_size_mb = Some(disk.size_gb * 1024); + self.selected_disk_size_mb = Some(disk.size_bytes / 1_048_576); + eprintln!("DEBUG AUTO DISK SELECT: disk={} size_bytes={} size_mb={}", disk.name, disk.size_bytes, disk.size_bytes / 1_048_576); state.partition_plan = make_plan(disk, self.is_uefi); } @@ -717,7 +718,8 @@ impl PartitionStep { if response.clicked() { state.selected_disk = Some(disk.name.clone()); - self.selected_disk_size_mb = Some(disk.size_gb * 1024); + self.selected_disk_size_mb = Some(disk.size_bytes / 1_048_576); + eprintln!("DEBUG DISK SELECT: disk={} size_bytes={} size_mb={}", disk.name, disk.size_bytes, disk.size_bytes / 1_048_576); state.custom_partitions = read_existing_partitions(&disk.name); self.manual.error = None; } @@ -738,11 +740,8 @@ impl PartitionStep { return; } }; - let disk_size_gb = state.available_disks.iter() - .find(|d| d.name == disk) - .map(|d| d.size_gb) - .unwrap_or(256); - let max_mb = (disk_size_gb as f64) * 1024.0; + let max_mb = self.selected_disk_size_mb.unwrap_or(256 * 1024) as f64; + eprintln!("DEBUG MAX_MB: selected_disk_size_mb={:?} max_mb={}", self.selected_disk_size_mb, max_mb); // ── Mevcut bölüm listesi tablosu ─────────────────────── ui.label(egui::RichText::new(t!("mp_plan_title")).strong().color(crate::ui::theme::c_text())); @@ -1054,6 +1053,9 @@ impl PartitionStep { .map(|(_, p)| p.size_mb) .sum(); let avail_mb = (max_mb as u64).saturating_sub(used_mb).max(1); + eprintln!("DEBUG EDIT: max_mb={} used_mb={} avail_mb={} edit_idx={:?} partitions={:?}", + max_mb, used_mb, avail_mb, self.manual.edit_idx, + state.custom_partitions.iter().map(|p| (p.mountpoint.clone(), p.size_mb)).collect::>()); let mut size_val = self.manual.add_size_str.trim().parse::().unwrap_or(0.0); ui.add_space(2.0); if ui.add(egui::Slider::new(&mut size_val, 0.0..=avail_mb as f64) @@ -1190,8 +1192,13 @@ impl PartitionStep { let size_mb: u64 = if size_str == "remaining" { // Kalan alanı hesapla if let Some(disk_size) = self.selected_disk_size_mb { - let used: u64 = state.custom_partitions.iter().map(|p| p.size_mb).sum(); + let used: u64 = state.custom_partitions.iter() + .enumerate() + .filter(|(i, _)| Some(*i) != self.manual.edit_idx) + .map(|(_, p)| p.size_mb) + .sum(); let remaining = disk_size.saturating_sub(used); + eprintln!("DEBUG REMAINING: disk_size={} used={} remaining={}", disk_size, used, remaining); if remaining > 0 { remaining } else { disk_size } } else { 0 diff --git a/src/ui/slideshow.rs b/src/ui/slideshow.rs index 02fd0be..2a6b2a7 100644 --- a/src/ui/slideshow.rs +++ b/src/ui/slideshow.rs @@ -109,12 +109,14 @@ impl Slideshow { None }; + // Kart, kendisine ayrılan dikey alanı doldursun. + let fill_h = ui.available_height().max(180.0); egui::Frame::none() .fill(crate::ui::theme::c_bg_widget()) .rounding(egui::Rounding::same(10.0)) .inner_margin(egui::Margin::same(24.0)) .show(ui, |ui| { - ui.set_min_height(180.0); + ui.set_min_height(fill_h); ui.vertical_centered(|ui| { // Simge veya Görsel if let Some(uri) = resolved_uri { @@ -147,45 +149,11 @@ impl Slideshow { .color(crate::ui::theme::c_text_dim()), ); - ui.add_space(16.0); - - // Nokta göstergesi - ui.horizontal(|ui| { - let dot_size = egui::vec2(8.0, 8.0); - for i in 0..self.slides.len() { - let color = if i == self.current { - crate::ui::theme::c_accent() - } else { - crate::ui::theme::c_border() - }; - let (rect, response) = ui.allocate_exact_size(dot_size, egui::Sense::click()); - ui.painter().circle_filled(rect.center(), 4.0, color); - if response.clicked() { - self.current = i; - self.last_advance = Instant::now(); - } - ui.add_space(4.0); - } }); - }); }); } pub fn slide_count(&self) -> usize { self.slides.len() } - - pub fn advance(&mut self) { - self.current = (self.current + 1) % self.slides.len(); - self.last_advance = Instant::now(); - } - - pub fn previous(&mut self) { - if self.current == 0 { - self.current = self.slides.len() - 1; - } else { - self.current -= 1; - } - self.last_advance = Instant::now(); - } }