inbox/list: Keep state between runs

This commit is contained in:
Erik Kundt
2026-01-11 01:03:25 +01:00
parent bdc0746ead
commit 41db809cb6
3 changed files with 42 additions and 17 deletions
+21 -5
View File
@@ -5,12 +5,13 @@ use std::ffi::OsString;
use anyhow::anyhow;
use radicle::node::notifications::NotificationId;
use radicle::storage::{HasRepoId, ReadRepository};
use radicle_cli::terminal::{Args, Error, Help};
use crate::terminal;
use crate::ui::items::notification::filter::{NotificationFilter, SortBy};
use crate::ui::items::notification::filter::SortBy;
use self::list::{InboxOperation, RepositoryMode};
@@ -58,7 +59,6 @@ pub enum OperationName {
#[derive(Debug, Default, Clone, PartialEq)]
pub struct ListOptions {
mode: RepositoryMode,
filter: NotificationFilter,
sort_by: SortBy,
json: bool,
}
@@ -179,11 +179,18 @@ pub async fn run(options: Options, ctx: impl radicle_cli::terminal::Context) ->
match options.op {
Operation::List { opts } => {
#[derive(Default)]
struct PreviousState {
notif_id: Option<NotificationId>,
search: Option<String>,
}
if let Err(err) = crate::log::enable() {
println!("{err}");
}
log::info!("Starting inbox listing interface in project {rid}..");
let mut state = PreviousState::default();
loop {
let profile = ctx.profile()?;
let repository = profile.storage.repository(rid)?;
@@ -193,8 +200,9 @@ pub async fn run(options: Options, ctx: impl radicle_cli::terminal::Context) ->
project: repository.identity_doc()?.project()?,
rid: repository.rid(),
mode: opts.mode.clone(),
filter: opts.filter.clone(),
search: state.search.clone(),
sort_by: opts.sort_by,
_notif_id: state.notif_id,
};
let app = list::Tui::new(context);
@@ -212,13 +220,21 @@ pub async fn run(options: Options, ctx: impl radicle_cli::terminal::Context) ->
} else if let Some(selection) = selection {
if let Some(operation) = selection.operation.clone() {
match operation {
InboxOperation::Show { id } => {
InboxOperation::Show { id, search } => {
state = PreviousState {
notif_id: Some(id),
search: Some(search),
};
terminal::run_rad(
Some("inbox"),
&["show".into(), id.to_string().into()],
)?;
}
InboxOperation::Clear { id } => {
InboxOperation::Clear { id, search } => {
state = PreviousState {
notif_id: Some(id),
search: Some(search),
};
terminal::run_rad(
Some("inbox"),
&["clear".into(), id.to_string().into()],
+20 -11
View File
@@ -48,8 +48,8 @@ pub enum RepositoryMode {
/// selection widget.
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub enum InboxOperation {
Show { id: NotificationId },
Clear { id: NotificationId },
Show { id: NotificationId, search: String },
Clear { id: NotificationId, search: String },
}
type Selection = tui::Selection<InboxOperation>;
@@ -85,8 +85,9 @@ pub struct Context {
pub project: Project,
pub rid: RepoId,
pub mode: RepositoryMode,
pub filter: NotificationFilter,
pub sort_by: SortBy,
pub _notif_id: Option<NotificationId>,
pub search: Option<String>,
}
pub struct Tui {
@@ -174,12 +175,17 @@ impl TryFrom<&Context> for App {
type Error = anyhow::Error;
fn try_from(context: &Context) -> Result<Self, Self::Error> {
let search = {
let raw = context.filter.to_string();
raw.trim().to_string()
let search = context.search.as_ref().map(|s| s.trim().to_string());
let (search, filter) = match search {
Some(search) => (
search.clone(),
NotificationFilter::from_str(search.trim()).unwrap_or(NotificationFilter::Invalid),
),
None => {
let filter = NotificationFilter::default();
(filter.to_string().trim().to_string(), filter)
}
};
let filter = NotificationFilter::from_str(&context.filter.to_string())
.unwrap_or(NotificationFilter::Invalid);
Ok(App {
context: Arc::new(Mutex::new(context.clone())),
@@ -189,8 +195,8 @@ impl TryFrom<&Context> for App {
main_group: ContainerState::new(3, Some(0)),
patches: TableState::new(Some(0)),
search: BufferedValue::new(TextEditState {
text: search.clone(),
cursor: search.len(),
text: search.to_string(),
cursor: search.chars().count(),
}),
show_search: false,
help: TextViewState::new(Position::default()),
@@ -421,6 +427,7 @@ impl App {
ui.send_message(Message::Exit {
operation: Some(InboxOperation::Show {
id: notification.id,
search: self.state.search.read().text,
}),
});
}
@@ -428,6 +435,7 @@ impl App {
ui.send_message(Message::Exit {
operation: Some(InboxOperation::Clear {
id: notification.id,
search: self.state.search.read().text,
}),
});
}
@@ -554,7 +562,8 @@ impl App {
Column::new(
Span::raw(format!(" {search} "))
.into_left_aligned_line()
.style(ui.theme().bar_on_black_style),
.style(ui.theme().bar_on_black_style)
.cyan(),
Constraint::Fill(1),
),
Column::new(
+1 -1
View File
@@ -7,7 +7,7 @@ use serde::Serialize;
use anyhow::{bail, Result};
use ratatui::layout::{Alignment, Constraint, Layout, Position};
use ratatui::style::{Style, Stylize};
use ratatui::style::Stylize;
use ratatui::text::{Line, Span, Text};
use ratatui::{Frame, Viewport};