final polish
This commit is contained in:
parent
dade4e204b
commit
b23c89cc1f
1 changed files with 66 additions and 26 deletions
63
src/app.rs
63
src/app.rs
|
|
@ -8,7 +8,7 @@ use std::collections::HashMap;
|
|||
use crate::config::Config;
|
||||
use crate::countries::{get_countries, Country};
|
||||
use crate::flags;
|
||||
use crate::nordvpn::{self, CmdResult, Poller};
|
||||
use crate::nordvpn::{self, CmdResult, Poller, StatusInfo};
|
||||
use crate::ui::config_dialog::{ConfigDialog, DialogResult};
|
||||
use crate::ui::country_selector::CountrySelector;
|
||||
use crate::world_map::WorldMap;
|
||||
|
|
@ -28,10 +28,12 @@ pub struct App {
|
|||
config_dialog: Option<ConfigDialog>,
|
||||
/// Last connect/disconnect result shown inline below the status bar.
|
||||
notification: Option<String>,
|
||||
/// A connect key that is awaiting user confirmation before being dispatched.
|
||||
pending_connect: Option<String>,
|
||||
}
|
||||
|
||||
impl App {
|
||||
pub fn new(cc: &eframe::CreationContext<'_>) -> Self {
|
||||
pub fn new(_cc: &eframe::CreationContext<'_>) -> Self {
|
||||
let config = Config::load();
|
||||
let countries = get_countries(&config.external_app);
|
||||
let poller = Poller::new(config.external_app.clone(), config.refresh_rate);
|
||||
|
|
@ -53,6 +55,7 @@ impl App {
|
|||
world_map: WorldMap::new(),
|
||||
config_dialog: None,
|
||||
notification: None,
|
||||
pending_connect: None,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -64,6 +67,16 @@ impl App {
|
|||
});
|
||||
}
|
||||
|
||||
/// If already connected, queue a confirmation prompt; otherwise connect immediately.
|
||||
fn request_connect(&mut self, key: String, status: &StatusInfo) {
|
||||
if status.is_connected() {
|
||||
self.pending_connect = Some(key);
|
||||
} else {
|
||||
self.notification = None;
|
||||
self.spawn_connect(key);
|
||||
}
|
||||
}
|
||||
|
||||
fn spawn_disconnect(&self) {
|
||||
let app = self.config.external_app.clone();
|
||||
let tx = self.cmd_tx.clone();
|
||||
|
|
@ -162,7 +175,7 @@ impl eframe::App for App {
|
|||
}
|
||||
|
||||
// ── Left panel — country selector ───────────────────────────────────
|
||||
let panel_width = ctx.screen_rect().width() * 0.3;
|
||||
let panel_width = ctx.content_rect().width() * 0.3;
|
||||
let connect_key =
|
||||
egui::SidePanel::left("country_selector")
|
||||
.exact_width(panel_width)
|
||||
|
|
@ -179,16 +192,52 @@ impl eframe::App for App {
|
|||
.inner;
|
||||
|
||||
if let Some(key) = connect_key {
|
||||
self.notification = None;
|
||||
self.spawn_connect(key);
|
||||
self.request_connect(key, &status);
|
||||
}
|
||||
|
||||
// ── Central panel — world map ────────────────────────────────────────
|
||||
egui::CentralPanel::default().show(ctx, |ui| {
|
||||
if let Some(key) = self.world_map.show(ui, &self.countries, status.country.as_deref()) {
|
||||
self.notification = None;
|
||||
self.spawn_connect(key);
|
||||
self.request_connect(key, &status);
|
||||
}
|
||||
});
|
||||
|
||||
// ── Confirmation modal ───────────────────────────────────────────────
|
||||
if let Some(key) = self.pending_connect.clone() {
|
||||
let label = self
|
||||
.countries
|
||||
.iter()
|
||||
.find(|c| c.nordvpn_key == key)
|
||||
.map(|c| c.name.as_str())
|
||||
.unwrap_or(key.as_str());
|
||||
|
||||
let mut confirmed = false;
|
||||
let mut cancelled = false;
|
||||
|
||||
egui::Window::new("Confirm")
|
||||
.collapsible(false)
|
||||
.resizable(false)
|
||||
.anchor(egui::Align2::CENTER_CENTER, [0.0, 0.0])
|
||||
.show(ctx, |ui| {
|
||||
ui.label(format!("Switch server to {}?", label));
|
||||
ui.add_space(8.0);
|
||||
ui.horizontal(|ui| {
|
||||
if ui.button("Connect").clicked() {
|
||||
confirmed = true;
|
||||
}
|
||||
if ui.button("Cancel").clicked() {
|
||||
cancelled = true;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
if confirmed {
|
||||
self.notification = None;
|
||||
self.spawn_connect(key);
|
||||
self.pending_connect = None;
|
||||
} else if cancelled {
|
||||
self.pending_connect = None;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue