tui: Improve cob retrieval
This commit is contained in:
parent
0d652d78e9
commit
a3077d5b15
|
|
@ -4,19 +4,18 @@ pub mod subscription;
|
||||||
|
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
|
|
||||||
use radicle::cob::issue::{IssueId, Issues};
|
use radicle::cob::issue::IssueId;
|
||||||
use radicle::cob::patch::{PatchId, Patches};
|
use radicle::cob::patch::PatchId;
|
||||||
use radicle::identity::{Id, Project};
|
use radicle::identity::{Id, Project};
|
||||||
use radicle::profile::Profile;
|
use radicle::profile::Profile;
|
||||||
use radicle::storage::ReadStorage;
|
|
||||||
|
|
||||||
use tuirealm::application::PollStrategy;
|
use tuirealm::application::PollStrategy;
|
||||||
use tuirealm::{Application, Frame, NoUserEvent};
|
use tuirealm::{Application, Frame, NoUserEvent};
|
||||||
|
|
||||||
use radicle_tui::ui;
|
|
||||||
use radicle_tui::ui::context::Context;
|
use radicle_tui::ui::context::Context;
|
||||||
use radicle_tui::ui::theme::{self, Theme};
|
use radicle_tui::ui::theme::{self, Theme};
|
||||||
use radicle_tui::Tui;
|
use radicle_tui::Tui;
|
||||||
|
use radicle_tui::{cob, ui};
|
||||||
|
|
||||||
use page::{HomeView, PatchView};
|
use page::{HomeView, PatchView};
|
||||||
|
|
||||||
|
|
@ -114,15 +113,9 @@ impl App {
|
||||||
id: PatchId,
|
id: PatchId,
|
||||||
theme: &Theme,
|
theme: &Theme,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
let repo = self
|
let repo = self.context.repository();
|
||||||
.context
|
|
||||||
.profile()
|
|
||||||
.storage
|
|
||||||
.repository(*self.context.id())
|
|
||||||
.unwrap();
|
|
||||||
let patches = Patches::open(&repo).unwrap();
|
|
||||||
|
|
||||||
if let Some(patch) = patches.get(&id)? {
|
if let Some(patch) = cob::patch::find(repo, &id)? {
|
||||||
let view = Box::new(PatchView::new((id, patch)));
|
let view = Box::new(PatchView::new((id, patch)));
|
||||||
self.pages.push(view, app, &self.context, theme)?;
|
self.pages.push(view, app, &self.context, theme)?;
|
||||||
|
|
||||||
|
|
@ -140,15 +133,9 @@ impl App {
|
||||||
id: IssueId,
|
id: IssueId,
|
||||||
theme: &Theme,
|
theme: &Theme,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
let repo = self
|
let repo = self.context.repository();
|
||||||
.context
|
|
||||||
.profile()
|
|
||||||
.storage
|
|
||||||
.repository(*self.context.id())
|
|
||||||
.unwrap();
|
|
||||||
let issues = Issues::open(&repo).unwrap();
|
|
||||||
|
|
||||||
if let Some(issue) = issues.get(&id)? {
|
if let Some(issue) = cob::issue::find(repo, &id)? {
|
||||||
let view = Box::new(IssuePage::new((id, issue)));
|
let view = Box::new(IssuePage::new((id, issue)));
|
||||||
self.pages.push(view, app, &self.context, theme)?;
|
self.pages.push(view, app, &self.context, theme)?;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1 +1,2 @@
|
||||||
|
pub mod issue;
|
||||||
pub mod patch;
|
pub mod patch;
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,19 @@
|
||||||
|
use anyhow::Result;
|
||||||
|
use radicle::cob::issue::{Issue, IssueId, Issues};
|
||||||
|
use radicle::storage::git::Repository;
|
||||||
|
|
||||||
|
pub fn all(repository: &Repository) -> Result<Vec<(IssueId, Issue)>> {
|
||||||
|
let patches = Issues::open(repository)?
|
||||||
|
.all()
|
||||||
|
.map(|iter| iter.flatten().collect::<Vec<_>>())?;
|
||||||
|
|
||||||
|
Ok(patches
|
||||||
|
.into_iter()
|
||||||
|
.map(|(id, issue, _)| (id, issue))
|
||||||
|
.collect::<Vec<_>>())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn find(repository: &Repository, id: &IssueId) -> Result<Option<Issue>> {
|
||||||
|
let issues = Issues::open(repository)?;
|
||||||
|
Ok(issues.get(id)?)
|
||||||
|
}
|
||||||
|
|
@ -1,50 +1,20 @@
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
|
|
||||||
use radicle::git::raw::Oid;
|
use radicle::cob::patch::{Patch, PatchId, Patches};
|
||||||
|
|
||||||
use radicle::cob::patch::{MergeTarget, Patch, PatchId, Patches};
|
|
||||||
use radicle::prelude::*;
|
|
||||||
use radicle::storage::git::Repository;
|
use radicle::storage::git::Repository;
|
||||||
|
|
||||||
pub fn load_all(profile: &Profile, id: Id) -> Vec<(PatchId, Patch)> {
|
pub fn all(repository: &Repository) -> Result<Vec<(PatchId, Patch)>> {
|
||||||
if let Ok(repository) = &profile.storage.repository(id) {
|
let patches = Patches::open(repository)?
|
||||||
if let Ok(proposed) = load_proposed(repository) {
|
.all()
|
||||||
return proposed;
|
.map(|iter| iter.flatten().collect::<Vec<_>>())?;
|
||||||
}
|
|
||||||
}
|
|
||||||
vec![]
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn load_proposed(repository: &Repository) -> Result<Vec<(PatchId, Patch)>> {
|
Ok(patches
|
||||||
let proposed = Patches::open(repository)?
|
.into_iter()
|
||||||
.proposed()?
|
|
||||||
.map(|(id, patch, _)| (id, patch))
|
.map(|(id, patch, _)| (id, patch))
|
||||||
.collect();
|
.collect::<Vec<_>>())
|
||||||
|
|
||||||
Ok(proposed)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn sync_status(repository: &Repository, patch: &Patch) -> Result<(usize, usize)> {
|
pub fn find(repository: &Repository, id: &PatchId) -> Result<Option<Patch>> {
|
||||||
let (_, revision) = patch.latest();
|
let patches = Patches::open(repository)?;
|
||||||
let target_oid = merge_target_oid(patch.target(), repository)?;
|
Ok(patches.get(id)?)
|
||||||
let (ahead, behind) = repository
|
|
||||||
.raw()
|
|
||||||
.graph_ahead_behind(*revision.head(), target_oid)?;
|
|
||||||
|
|
||||||
Ok((ahead, behind))
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn merge_target_oid(target: MergeTarget, repository: &Repository) -> Result<Oid> {
|
|
||||||
match target {
|
|
||||||
MergeTarget::Delegates => {
|
|
||||||
if let Ok((_, target)) = repository.head() {
|
|
||||||
Ok(*target)
|
|
||||||
} else {
|
|
||||||
anyhow::bail!(
|
|
||||||
"failed to determine default branch head for project {}",
|
|
||||||
repository.id,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,18 +1,24 @@
|
||||||
use radicle::prelude::{Id, Project};
|
use radicle::prelude::{Id, Project};
|
||||||
use radicle::Profile;
|
use radicle::Profile;
|
||||||
|
|
||||||
|
use radicle::storage::git::Repository;
|
||||||
|
use radicle::storage::ReadStorage;
|
||||||
|
|
||||||
pub struct Context {
|
pub struct Context {
|
||||||
profile: Profile,
|
profile: Profile,
|
||||||
id: Id,
|
id: Id,
|
||||||
project: Project,
|
project: Project,
|
||||||
|
repository: Repository,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Context {
|
impl Context {
|
||||||
pub fn new(profile: Profile, id: Id, project: Project) -> Self {
|
pub fn new(profile: Profile, id: Id, project: Project) -> Self {
|
||||||
|
let repository = profile.storage.repository(id).unwrap();
|
||||||
Self {
|
Self {
|
||||||
id,
|
id,
|
||||||
profile,
|
profile,
|
||||||
project,
|
project,
|
||||||
|
repository,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -27,4 +33,8 @@ impl Context {
|
||||||
pub fn project(&self) -> &Project {
|
pub fn project(&self) -> &Project {
|
||||||
&self.project
|
&self.project
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn repository(&self) -> &Repository {
|
||||||
|
&self.repository
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,3 @@
|
||||||
use radicle::cob::issue::Issues;
|
|
||||||
use radicle::storage::ReadStorage;
|
|
||||||
|
|
||||||
use radicle::cob::patch::Patches;
|
|
||||||
|
|
||||||
use tuirealm::command::{Cmd, CmdResult};
|
use tuirealm::command::{Cmd, CmdResult};
|
||||||
use tuirealm::tui::layout::Rect;
|
use tuirealm::tui::layout::Rect;
|
||||||
use tuirealm::{AttrValue, Attribute, Frame, MockComponent, Props, State};
|
use tuirealm::{AttrValue, Attribute, Frame, MockComponent, Props, State};
|
||||||
|
|
@ -14,6 +9,7 @@ use super::common::list::{ColumnWidth, Table};
|
||||||
|
|
||||||
use super::{Widget, WidgetComponent};
|
use super::{Widget, WidgetComponent};
|
||||||
|
|
||||||
|
use crate::cob;
|
||||||
use crate::ui::cob::{IssueItem, PatchItem};
|
use crate::ui::cob::{IssueItem, PatchItem};
|
||||||
use crate::ui::context::Context;
|
use crate::ui::context::Context;
|
||||||
use crate::ui::layout;
|
use crate::ui::layout;
|
||||||
|
|
@ -59,10 +55,6 @@ pub struct IssueBrowser {
|
||||||
|
|
||||||
impl IssueBrowser {
|
impl IssueBrowser {
|
||||||
pub fn new(context: &Context, theme: &Theme, shortcuts: Widget<Shortcuts>) -> Self {
|
pub fn new(context: &Context, theme: &Theme, shortcuts: Widget<Shortcuts>) -> Self {
|
||||||
let repo = context.profile().storage.repository(*context.id()).unwrap();
|
|
||||||
let issues = Issues::open(&repo)
|
|
||||||
.and_then(|issues| issues.all().map(|iter| iter.flatten().collect::<Vec<_>>()));
|
|
||||||
|
|
||||||
let header = [
|
let header = [
|
||||||
common::label(" ● "),
|
common::label(" ● "),
|
||||||
common::label("ID"),
|
common::label("ID"),
|
||||||
|
|
@ -83,10 +75,12 @@ impl IssueBrowser {
|
||||||
ColumnWidth::Fixed(18),
|
ColumnWidth::Fixed(18),
|
||||||
];
|
];
|
||||||
|
|
||||||
|
let repo = context.repository();
|
||||||
let mut items = vec![];
|
let mut items = vec![];
|
||||||
if let Ok(issues) = issues {
|
|
||||||
for (id, patch, _) in issues {
|
if let Ok(issues) = cob::issue::all(repo) {
|
||||||
if let Ok(item) = IssueItem::try_from((context.profile(), &repo, id, patch)) {
|
for (id, issue) in issues {
|
||||||
|
if let Ok(item) = IssueItem::try_from((context.profile(), repo, id, issue)) {
|
||||||
items.push(item);
|
items.push(item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -135,10 +129,6 @@ pub struct PatchBrowser {
|
||||||
|
|
||||||
impl PatchBrowser {
|
impl PatchBrowser {
|
||||||
pub fn new(context: &Context, theme: &Theme, shortcuts: Widget<Shortcuts>) -> Self {
|
pub fn new(context: &Context, theme: &Theme, shortcuts: Widget<Shortcuts>) -> Self {
|
||||||
let repo = context.profile().storage.repository(*context.id()).unwrap();
|
|
||||||
let patches = Patches::open(&repo)
|
|
||||||
.and_then(|patches| patches.all().map(|iter| iter.flatten().collect::<Vec<_>>()));
|
|
||||||
|
|
||||||
let header = [
|
let header = [
|
||||||
common::label(" ● "),
|
common::label(" ● "),
|
||||||
common::label("ID"),
|
common::label("ID"),
|
||||||
|
|
@ -161,10 +151,12 @@ impl PatchBrowser {
|
||||||
ColumnWidth::Fixed(18),
|
ColumnWidth::Fixed(18),
|
||||||
];
|
];
|
||||||
|
|
||||||
|
let repo = context.repository();
|
||||||
let mut items = vec![];
|
let mut items = vec![];
|
||||||
if let Ok(patches) = patches {
|
|
||||||
for (id, patch, _) in patches {
|
if let Ok(patches) = cob::patch::all(repo) {
|
||||||
if let Ok(item) = PatchItem::try_from((context.profile(), &repo, id, patch)) {
|
for (id, patch) in patches {
|
||||||
|
if let Ok(item) = PatchItem::try_from((context.profile(), repo, id, patch)) {
|
||||||
items.push(item);
|
items.push(item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue