feat(ui): render remote context menu with delete confirmation and info windows

This commit is contained in:
Black_Raven committed 2026-08-13 18:38:58 +03:00
1 parent 1679c8b08e
commit 8d213972d6
1 file changed
+145 -8
+145 -8
View File
@@ -7,6 +7,14 @@ use egui::{
use std::path::Path; use std::path::Path;
use std::time::Duration; use std::time::Duration;
/// Действия контекстного меню хранилища
enum RemoteMenuAction {
Open,
Check,
About,
Delete,
}
impl eframe::App for RcloneUI { impl eframe::App for RcloneUI {
fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) { fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) {
self.poll_rclone_init(); self.poll_rclone_init();
@@ -42,16 +50,21 @@ impl eframe::App for RcloneUI {
ui.separator(); ui.separator();
ScrollArea::vertical().show(ui, |ui| { ScrollArea::vertical().show(ui, |ui| {
for remote in self.remote_list.clone() { for remote in self.remote_list.clone() {
if ui let selected = self.current_path.starts_with(&remote.name);
.selectable_label( let response =
self.current_path.starts_with(&remote.name), ui.selectable_label(selected, format!("📡 {}", remote.name));
format!("📡 {}", remote.name), if response.clicked() {
) log::debug!("Открытие remote: {}", remote.name);
.clicked()
{
log::debug!("Выбрано удаленное хранилище: {}", remote.name);
self.navigate_to(format!("{}:", remote.name)); self.navigate_to(format!("{}:", remote.name));
} }
if response.secondary_clicked() {
log::debug!("Контекстное меню remote: {}", remote.name);
let pos = ctx
.input(|i| i.pointer.interact_pos())
.unwrap_or_default();
self.context_menu = Some((remote.name.clone(), pos));
self.context_menu_requested = true;
}
} }
}); });
ui.separator(); ui.separator();
@@ -480,6 +493,130 @@ impl eframe::App for RcloneUI {
} }
} }
// Подтверждение удаления хранилища
if let Some(remote_name) = self.remote_to_delete.clone() {
let mut close = false;
let mut confirm = false;
Window::new("Удаление хранилища")
.anchor(Align2::CENTER_CENTER, [0.0, 0.0])
.collapsible(false)
.resizable(false)
.fixed_size([430.0, 170.0])
.show(ctx, |ui| {
ui.label(format!("Удалить хранилище «{}»?", remote_name));
ui.add(
egui::Label::new(
"Файлы в облаке не удаляются — удаляется только запись из конфигурации rclone.",
)
.wrap(true),
);
ui.separator();
ui.horizontal(|ui| {
if ui.button("🗑️ Удалить").clicked() {
confirm = true;
}
if ui.button("Отмена").clicked() {
close = true;
}
});
});
if close {
self.remote_to_delete = None;
}
if confirm {
self.remote_to_delete = None;
self.delete_remote(remote_name);
}
}
// Окно с результатом проверки или информацией о хранилище
if let Some(info) = &self.remote_info {
let mut close = false;
Window::new(&info.title)
.anchor(Align2::CENTER_CENTER, [0.0, 0.0])
.collapsible(false)
.resizable(false)
.fixed_size([430.0, 260.0])
.show(ctx, |ui| {
let color = if info.success {
Color32::LIGHT_GREEN
} else {
Color32::KHAKI
};
ui.add(
egui::Label::new(egui::RichText::new(&info.content).color(color))
.wrap(true),
);
ui.separator();
if ui.button("ОК").clicked() {
close = true;
}
});
if close {
self.remote_info = None;
}
}
// Контекстное меню хранилища (правая кнопка мыши)
if let Some((menu_name, menu_pos)) = self.context_menu.clone() {
let remote_type = self
.remote_list
.iter()
.find(|r| r.name == menu_name)
.map(|r| r.r#type.clone())
.unwrap_or_default();
let mut action: Option<RemoteMenuAction> = None;
Window::new("remote_menu")
.title_bar(false)
.resizable(false)
.collapsible(false)
.fixed_pos(menu_pos)
.show(ctx, |ui| {
ui.weak(format!("Тип: {}", remote_type));
ui.separator();
if ui.button("📂 Открыть").clicked() {
action = Some(RemoteMenuAction::Open);
}
if ui.button("🔍 Проверить доступность").clicked() {
action = Some(RemoteMenuAction::Check);
}
if ui.button("📊 Использование").clicked() {
action = Some(RemoteMenuAction::About);
}
ui.separator();
if ui.button("🗑️ Удалить").clicked() {
action = Some(RemoteMenuAction::Delete);
}
});
if let Some(action) = action {
self.context_menu = None;
match action {
RemoteMenuAction::Open => {
log::debug!("Открытие remote из меню: {}", menu_name);
self.navigate_to(format!("{}:", menu_name));
}
RemoteMenuAction::Check => {
log::debug!("Проверка remote из меню: {}", menu_name);
self.check_remote(menu_name.clone());
}
RemoteMenuAction::About => {
log::debug!("Использование remote из меню: {}", menu_name);
self.about_remote(menu_name.clone());
}
RemoteMenuAction::Delete => {
log::debug!("Запрос удаления remote из меню: {}", menu_name);
self.remote_to_delete = Some(menu_name.clone());
}
}
} else {
let just_opened = std::mem::take(&mut self.context_menu_requested);
if !just_opened && ctx.input(|i| i.pointer.any_click()) {
log::debug!("Контекстное меню закрыто");
self.context_menu = None;
}
}
}
if let Some(path) = self.pending_load_path.take() { if let Some(path) = self.pending_load_path.take() {
self.current_path = path.clone(); self.current_path = path.clone();
self.selected_paths.clear(); self.selected_paths.clear();