tui: Fix global navigation subscriptions
This commit is contained in:
parent
97f122c451
commit
474d21741e
|
|
@ -1,10 +1,9 @@
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
|
|
||||||
use radicle::cob::{
|
use radicle::cob::issue::{Issue, IssueId};
|
||||||
issue::{Issue, IssueId},
|
use radicle::cob::patch::{Patch, PatchId};
|
||||||
patch::{Patch, PatchId},
|
|
||||||
};
|
use tuirealm::{Frame, NoUserEvent, Sub, SubClause};
|
||||||
use tuirealm::{Frame, NoUserEvent};
|
|
||||||
|
|
||||||
use radicle_tui::ui::layout;
|
use radicle_tui::ui::layout;
|
||||||
use radicle_tui::ui::theme::Theme;
|
use radicle_tui::ui::theme::Theme;
|
||||||
|
|
@ -41,6 +40,14 @@ pub trait ViewPage {
|
||||||
|
|
||||||
/// Will be called whenever a view page is on top of the page stack and needs to be rendered.
|
/// Will be called whenever a view page is on top of the page stack and needs to be rendered.
|
||||||
fn view(&mut self, app: &mut Application<Cid, Message, NoUserEvent>, frame: &mut Frame);
|
fn view(&mut self, app: &mut Application<Cid, Message, NoUserEvent>, frame: &mut Frame);
|
||||||
|
|
||||||
|
/// Will be called whenever this view page is pushed to the stack, or it is on top of the stack again
|
||||||
|
/// after another view page was popped from the stack.
|
||||||
|
fn subscribe(&self, app: &mut Application<Cid, Message, NoUserEvent>) -> Result<()>;
|
||||||
|
|
||||||
|
/// Will be called whenever this view page is on top of the stack and another view page is pushed
|
||||||
|
/// to the stack, or if this is popped from the stack.
|
||||||
|
fn unsubscribe(&self, app: &mut Application<Cid, Message, NoUserEvent>) -> Result<()>;
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
|
|
@ -71,11 +78,7 @@ impl ViewPage for HomeView {
|
||||||
let issue_browser = widget::home::issues(theme, &context.id, &context.profile).to_boxed();
|
let issue_browser = widget::home::issues(theme, &context.id, &context.profile).to_boxed();
|
||||||
let patch_browser = widget::home::patches(theme, &context.id, &context.profile).to_boxed();
|
let patch_browser = widget::home::patches(theme, &context.id, &context.profile).to_boxed();
|
||||||
|
|
||||||
app.remount(
|
app.remount(Cid::Home(HomeCid::Navigation), navigation, vec![])?;
|
||||||
Cid::Home(HomeCid::Navigation),
|
|
||||||
navigation,
|
|
||||||
subscription::navigation(),
|
|
||||||
)?;
|
|
||||||
|
|
||||||
app.remount(Cid::Home(HomeCid::Dashboard), dashboard, vec![])?;
|
app.remount(Cid::Home(HomeCid::Dashboard), dashboard, vec![])?;
|
||||||
app.remount(Cid::Home(HomeCid::IssueBrowser), issue_browser, vec![])?;
|
app.remount(Cid::Home(HomeCid::IssueBrowser), issue_browser, vec![])?;
|
||||||
|
|
@ -114,6 +117,27 @@ impl ViewPage for HomeView {
|
||||||
app.view(&Cid::Home(HomeCid::Navigation), frame, layout[0]);
|
app.view(&Cid::Home(HomeCid::Navigation), frame, layout[0]);
|
||||||
app.view(&self.active_component, frame, layout[1]);
|
app.view(&self.active_component, frame, layout[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn subscribe(&self, app: &mut Application<Cid, Message, NoUserEvent>) -> Result<()> {
|
||||||
|
app.subscribe(
|
||||||
|
&Cid::Home(HomeCid::Navigation),
|
||||||
|
Sub::new(
|
||||||
|
subscription::navigation_clause::<Cid, _>(),
|
||||||
|
SubClause::Always,
|
||||||
|
),
|
||||||
|
)?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn unsubscribe(&self, app: &mut Application<Cid, Message, NoUserEvent>) -> Result<()> {
|
||||||
|
app.unsubscribe(
|
||||||
|
&Cid::Home(HomeCid::Navigation),
|
||||||
|
subscription::navigation_clause::<Cid, _>(),
|
||||||
|
)?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
|
|
@ -171,6 +195,27 @@ impl ViewPage for IssuePage {
|
||||||
app.view(&Cid::Patch(PatchCid::Navigation), frame, layout[0]);
|
app.view(&Cid::Patch(PatchCid::Navigation), frame, layout[0]);
|
||||||
app.view(&self.active_component, frame, layout[1]);
|
app.view(&self.active_component, frame, layout[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn subscribe(&self, app: &mut Application<Cid, Message, NoUserEvent>) -> Result<()> {
|
||||||
|
app.subscribe(
|
||||||
|
&Cid::Home(HomeCid::Navigation),
|
||||||
|
Sub::new(
|
||||||
|
subscription::navigation_clause::<Cid, _>(),
|
||||||
|
SubClause::Always,
|
||||||
|
),
|
||||||
|
)?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn unsubscribe(&self, app: &mut Application<Cid, Message, NoUserEvent>) -> Result<()> {
|
||||||
|
app.unsubscribe(
|
||||||
|
&Cid::Home(HomeCid::Navigation),
|
||||||
|
subscription::navigation_clause::<Cid, _>(),
|
||||||
|
)?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
|
|
@ -202,11 +247,7 @@ impl ViewPage for PatchView {
|
||||||
let activity = widget::patch::activity(theme, (*id, patch), &context.profile).to_boxed();
|
let activity = widget::patch::activity(theme, (*id, patch), &context.profile).to_boxed();
|
||||||
let files = widget::patch::files(theme, (*id, patch), &context.profile).to_boxed();
|
let files = widget::patch::files(theme, (*id, patch), &context.profile).to_boxed();
|
||||||
|
|
||||||
app.remount(
|
app.remount(Cid::Patch(PatchCid::Navigation), navigation, vec![])?;
|
||||||
Cid::Patch(PatchCid::Navigation),
|
|
||||||
navigation,
|
|
||||||
subscription::navigation(),
|
|
||||||
)?;
|
|
||||||
app.remount(Cid::Patch(PatchCid::Activity), activity, vec![])?;
|
app.remount(Cid::Patch(PatchCid::Activity), activity, vec![])?;
|
||||||
app.remount(Cid::Patch(PatchCid::Files), files, vec![])?;
|
app.remount(Cid::Patch(PatchCid::Files), files, vec![])?;
|
||||||
|
|
||||||
|
|
@ -242,6 +283,27 @@ impl ViewPage for PatchView {
|
||||||
app.view(&Cid::Patch(PatchCid::Navigation), frame, layout[0]);
|
app.view(&Cid::Patch(PatchCid::Navigation), frame, layout[0]);
|
||||||
app.view(&self.active_component, frame, layout[1]);
|
app.view(&self.active_component, frame, layout[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn subscribe(&self, app: &mut Application<Cid, Message, NoUserEvent>) -> Result<()> {
|
||||||
|
app.subscribe(
|
||||||
|
&Cid::Patch(PatchCid::Navigation),
|
||||||
|
Sub::new(
|
||||||
|
subscription::navigation_clause::<Cid, _>(),
|
||||||
|
SubClause::Always,
|
||||||
|
),
|
||||||
|
)?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn unsubscribe(&self, app: &mut Application<Cid, Message, NoUserEvent>) -> Result<()> {
|
||||||
|
app.unsubscribe(
|
||||||
|
&Cid::Patch(PatchCid::Navigation),
|
||||||
|
subscription::navigation_clause::<Cid, _>(),
|
||||||
|
)?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// View pages need to preserve their state (e.g. selected navigation tab, contents
|
/// View pages need to preserve their state (e.g. selected navigation tab, contents
|
||||||
|
|
@ -265,16 +327,25 @@ impl PageStack {
|
||||||
context: &Context,
|
context: &Context,
|
||||||
theme: &Theme,
|
theme: &Theme,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
|
if let Some(page) = self.pages.last() {
|
||||||
|
page.unsubscribe(app)?;
|
||||||
|
}
|
||||||
|
|
||||||
page.mount(app, context, theme)?;
|
page.mount(app, context, theme)?;
|
||||||
|
page.subscribe(app)?;
|
||||||
|
|
||||||
self.pages.push(page);
|
self.pages.push(page);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn pop(&mut self, app: &mut Application<Cid, Message, NoUserEvent>) -> Result<()> {
|
pub fn pop(&mut self, app: &mut Application<Cid, Message, NoUserEvent>) -> Result<()> {
|
||||||
|
self.peek_mut()?.unsubscribe(app)?;
|
||||||
self.peek_mut()?.unmount(app)?;
|
self.peek_mut()?.unmount(app)?;
|
||||||
self.pages.pop();
|
self.pages.pop();
|
||||||
|
|
||||||
|
self.peek_mut()?.subscribe(app)?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,18 +3,15 @@ use std::hash::Hash;
|
||||||
use tuirealm::event::{Key, KeyEvent, KeyModifiers};
|
use tuirealm::event::{Key, KeyEvent, KeyModifiers};
|
||||||
use tuirealm::{Sub, SubClause, SubEventClause};
|
use tuirealm::{Sub, SubClause, SubEventClause};
|
||||||
|
|
||||||
pub fn navigation<Id, UserEvent>() -> Vec<Sub<Id, UserEvent>>
|
pub fn navigation_clause<Id, UserEvent>() -> SubEventClause<UserEvent>
|
||||||
where
|
where
|
||||||
Id: Clone + Hash + Eq + PartialEq,
|
Id: Clone + Hash + Eq + PartialEq,
|
||||||
UserEvent: Clone + Eq + PartialEq + PartialOrd,
|
UserEvent: Clone + Eq + PartialEq + PartialOrd,
|
||||||
{
|
{
|
||||||
vec![Sub::new(
|
SubEventClause::Keyboard(KeyEvent {
|
||||||
SubEventClause::Keyboard(KeyEvent {
|
code: Key::Tab,
|
||||||
code: Key::Tab,
|
modifiers: KeyModifiers::NONE,
|
||||||
modifiers: KeyModifiers::NONE,
|
})
|
||||||
}),
|
|
||||||
SubClause::Always,
|
|
||||||
)]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn global<Id, UserEvent>() -> Vec<Sub<Id, UserEvent>>
|
pub fn global<Id, UserEvent>() -> Vec<Sub<Id, UserEvent>>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue