Radish alpha
r
rad:z39mP9rQAaGmERfUMPULfPUi473tY
Radicle terminal user interface
Radicle
Git
inbox/list: Keep state between runs
Erik Kundt committed 3 months ago
commit 41db809cb6c8e42745de6ab007f67a35c62001e5
parent bdc0746
3 files changed +42 -17
modified bin/commands/inbox.rs
@@ -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()],
modified bin/commands/inbox/list.rs
@@ -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(
modified bin/commands/issue/list.rs
@@ -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};