Confirm session deletion
This commit is contained in:
34
src/app.rs
34
src/app.rs
@@ -65,6 +65,8 @@ pub(crate) struct App {
|
|||||||
drafts: HashMap<i32, String>,
|
drafts: HashMap<i32, String>,
|
||||||
/// Session whose quick-actions menu is open.
|
/// Session whose quick-actions menu is open.
|
||||||
session_menu: Option<i32>,
|
session_menu: Option<i32>,
|
||||||
|
/// Session waiting for explicit confirmation before deletion.
|
||||||
|
pending_session_delete: Option<i32>,
|
||||||
/// Session being renamed, with the in-progress title.
|
/// Session being renamed, with the in-progress title.
|
||||||
session_rename: Option<(i32, String)>,
|
session_rename: Option<(i32, String)>,
|
||||||
/// Projects whose archived sessions are expanded in the sidebar.
|
/// Projects whose archived sessions are expanded in the sidebar.
|
||||||
@@ -255,7 +257,8 @@ pub(crate) enum Message {
|
|||||||
CreateSession(i32),
|
CreateSession(i32),
|
||||||
DiscardSession(i32),
|
DiscardSession(i32),
|
||||||
SelectSession(i32, i32),
|
SelectSession(i32, i32),
|
||||||
DeleteSession(i32),
|
RequestDeleteSession(i32),
|
||||||
|
ConfirmDeleteSession,
|
||||||
OpenSessionMenu(i32),
|
OpenSessionMenu(i32),
|
||||||
StartRenameSession(i32),
|
StartRenameSession(i32),
|
||||||
SessionTitleChanged(String),
|
SessionTitleChanged(String),
|
||||||
@@ -327,6 +330,7 @@ impl App {
|
|||||||
selected_session: None,
|
selected_session: None,
|
||||||
drafts,
|
drafts,
|
||||||
session_menu: None,
|
session_menu: None,
|
||||||
|
pending_session_delete: None,
|
||||||
session_rename: None,
|
session_rename: None,
|
||||||
expanded_archives: HashSet::new(),
|
expanded_archives: HashSet::new(),
|
||||||
sidebar_drag: false,
|
sidebar_drag: false,
|
||||||
@@ -446,6 +450,7 @@ impl App {
|
|||||||
selected_session: None,
|
selected_session: None,
|
||||||
drafts: HashMap::new(),
|
drafts: HashMap::new(),
|
||||||
session_menu: None,
|
session_menu: None,
|
||||||
|
pending_session_delete: None,
|
||||||
session_rename: None,
|
session_rename: None,
|
||||||
expanded_archives: HashSet::new(),
|
expanded_archives: HashSet::new(),
|
||||||
sidebar_drag: false,
|
sidebar_drag: false,
|
||||||
@@ -556,7 +561,9 @@ impl App {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
Message::DismissPanel => {
|
Message::DismissPanel => {
|
||||||
if self.pending_a2ui_dismissal.is_some() {
|
if self.pending_session_delete.is_some() {
|
||||||
|
self.pending_session_delete = None;
|
||||||
|
} else if self.pending_a2ui_dismissal.is_some() {
|
||||||
self.pending_a2ui_dismissal = None;
|
self.pending_a2ui_dismissal = None;
|
||||||
} else if self.session_rename.is_some() || self.session_menu.is_some() {
|
} else if self.session_rename.is_some() || self.session_menu.is_some() {
|
||||||
self.session_rename = None;
|
self.session_rename = None;
|
||||||
@@ -1351,7 +1358,28 @@ impl App {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Message::DeleteSession(session_id) => {
|
Message::RequestDeleteSession(session_id) => {
|
||||||
|
if self.generating && self.selected_session == Some(session_id) {
|
||||||
|
self.error =
|
||||||
|
Some("Stop the active generation before deleting its session.".into());
|
||||||
|
return Task::none();
|
||||||
|
}
|
||||||
|
if self
|
||||||
|
.projects
|
||||||
|
.iter()
|
||||||
|
.flat_map(|project| &project.sessions)
|
||||||
|
.any(|session| session.id == session_id)
|
||||||
|
{
|
||||||
|
self.pending_session_delete = Some(session_id);
|
||||||
|
self.session_menu = None;
|
||||||
|
self.session_rename = None;
|
||||||
|
self.error = None;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Message::ConfirmDeleteSession => {
|
||||||
|
let Some(session_id) = self.pending_session_delete.take() else {
|
||||||
|
return Task::none();
|
||||||
|
};
|
||||||
if self.generating && self.selected_session == Some(session_id) {
|
if self.generating && self.selected_session == Some(session_id) {
|
||||||
self.error =
|
self.error =
|
||||||
Some("Stop the active generation before deleting its session.".into());
|
Some("Stop the active generation before deleting its session.".into());
|
||||||
|
|||||||
@@ -70,6 +70,7 @@ impl App {
|
|||||||
pub(super) fn modal_open(&self) -> bool {
|
pub(super) fn modal_open(&self) -> bool {
|
||||||
self.preferences_open
|
self.preferences_open
|
||||||
|| self.pending_project_path.is_some()
|
|| self.pending_project_path.is_some()
|
||||||
|
|| self.pending_session_delete.is_some()
|
||||||
|| self.session_rename.is_some()
|
|| self.session_rename.is_some()
|
||||||
|| self.menu_session().is_some()
|
|| self.menu_session().is_some()
|
||||||
|| self.pending_a2ui_dismissal.is_some()
|
|| self.pending_a2ui_dismissal.is_some()
|
||||||
@@ -136,6 +137,8 @@ impl App {
|
|||||||
layers.push(self.project_dialog(path));
|
layers.push(self.project_dialog(path));
|
||||||
} else if let Some((_, title)) = &self.session_rename {
|
} else if let Some((_, title)) = &self.session_rename {
|
||||||
layers.push(self.rename_dialog(title));
|
layers.push(self.rename_dialog(title));
|
||||||
|
} else if let Some(session) = self.pending_delete_session() {
|
||||||
|
layers.push(self.delete_session_panel(session));
|
||||||
} else if let Some(session) = self.menu_session() {
|
} else if let Some(session) = self.menu_session() {
|
||||||
layers.push(self.session_menu_panel(session));
|
layers.push(self.session_menu_panel(session));
|
||||||
} else if let Some(surface_id) = &self.pending_a2ui_dismissal {
|
} else if let Some(surface_id) = &self.pending_a2ui_dismissal {
|
||||||
@@ -150,6 +153,8 @@ impl App {
|
|||||||
layers.push(self.project_dialog(path));
|
layers.push(self.project_dialog(path));
|
||||||
} else if let Some((_, title)) = &self.session_rename {
|
} else if let Some((_, title)) = &self.session_rename {
|
||||||
layers.push(self.rename_dialog(title));
|
layers.push(self.rename_dialog(title));
|
||||||
|
} else if let Some(session) = self.pending_delete_session() {
|
||||||
|
layers.push(self.delete_session_panel(session));
|
||||||
} else if let Some(session) = self.menu_session() {
|
} else if let Some(session) = self.menu_session() {
|
||||||
layers.push(self.session_menu_panel(session));
|
layers.push(self.session_menu_panel(session));
|
||||||
} else if let Some(surface_id) = &self.pending_a2ui_dismissal {
|
} else if let Some(surface_id) = &self.pending_a2ui_dismissal {
|
||||||
@@ -389,7 +394,7 @@ impl App {
|
|||||||
.on_press(Message::OpenSessionMenu(session.id))
|
.on_press(Message::OpenSessionMenu(session.id))
|
||||||
.style(button::text),
|
.style(button::text),
|
||||||
button(icon(ICON_TRASH, 14))
|
button(icon(ICON_TRASH, 14))
|
||||||
.on_press(Message::DeleteSession(session.id))
|
.on_press(Message::RequestDeleteSession(session.id))
|
||||||
.style(button::text),
|
.style(button::text),
|
||||||
]
|
]
|
||||||
.spacing(3)
|
.spacing(3)
|
||||||
@@ -508,12 +513,53 @@ impl App {
|
|||||||
|
|
||||||
fn menu_session(&self) -> Option<&Session> {
|
fn menu_session(&self) -> Option<&Session> {
|
||||||
let session_id = self.session_menu?;
|
let session_id = self.session_menu?;
|
||||||
|
self.session(session_id)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn pending_delete_session(&self) -> Option<&Session> {
|
||||||
|
let session_id = self.pending_session_delete?;
|
||||||
|
self.session(session_id)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn session(&self, session_id: i32) -> Option<&Session> {
|
||||||
self.projects
|
self.projects
|
||||||
.iter()
|
.iter()
|
||||||
.flat_map(|project| &project.sessions)
|
.flat_map(|project| &project.sessions)
|
||||||
.find(|session| session.id == session_id)
|
.find(|session| session.id == session_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn delete_session_panel<'a>(&self, session: &'a Session) -> Element<'a, Message> {
|
||||||
|
let dialog = container(
|
||||||
|
column![
|
||||||
|
text("Delete session?").size(24),
|
||||||
|
text(format!(
|
||||||
|
"Delete “{}” and its conversation history? This cannot be undone.",
|
||||||
|
session.title
|
||||||
|
))
|
||||||
|
.size(14),
|
||||||
|
row![
|
||||||
|
Space::new().width(Length::Fill),
|
||||||
|
action_button("Cancel").on_press(Message::DismissPanel),
|
||||||
|
danger_button("Delete session").on_press(Message::ConfirmDeleteSession),
|
||||||
|
]
|
||||||
|
.spacing(8),
|
||||||
|
]
|
||||||
|
.spacing(12),
|
||||||
|
)
|
||||||
|
.padding(22)
|
||||||
|
.width(460)
|
||||||
|
.style(overview_style);
|
||||||
|
|
||||||
|
opaque(
|
||||||
|
container(dialog)
|
||||||
|
.center_x(Length::Fill)
|
||||||
|
.center_y(Length::Fill)
|
||||||
|
.style(|_| {
|
||||||
|
container::Style::default().background(Color::from_rgba8(0, 0, 0, 0.68))
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
/// Quick actions for one session. Which lifecycle moves are offered depends
|
/// Quick actions for one session. Which lifecycle moves are offered depends
|
||||||
/// on the state the session is in.
|
/// on the state the session is in.
|
||||||
fn session_menu_panel<'a>(&self, session: &'a Session) -> Element<'a, Message> {
|
fn session_menu_panel<'a>(&self, session: &'a Session) -> Element<'a, Message> {
|
||||||
|
|||||||
Reference in New Issue
Block a user