use crate::ui::utils::remove_view_from_layout;
use crate::wiki::{
article::{
parser::{DefaultParser, Parser},
Article, ArticleBuilder,
},
search::SearchResult,
};
use crate::{config, ui, view_with_theme};
use anyhow::{bail, Context, Result};
use cursive::align::HAlign;
use cursive::view::{Nameable, Scrollable};
use cursive::views::{Dialog, LinearLayout, TextView};
use cursive::Cursive;
mod content;
mod lines;
mod links;
mod view;
pub type ArticleView = view::ArticleView;
pub fn on_article_submit(siv: &mut Cursive, search_result: &SearchResult) {
log::info!("on_article_submit was called");
log::info!(
"fetching the article '{}' with the id '{}'",
search_result.title(),
search_result.page_id()
);
let article = match ArticleBuilder::new(*search_result.page_id(), None)
.build(&mut DefaultParser::new(&config::CONFIG.parser))
{
Ok(article) => article,
Err(error) => {
log::warn!("{}", error);
siv.add_layer(
Dialog::info("A Problem occurred while fetching the article.\nCheck the logs for further information")
.title("Error")
.title_position(HAlign::Center)
);
log::info!("on_article_submit failed to finish");
return;
}
};
log::info!(
"displaying the article '{}'",
if search_result.title().is_empty() {
search_result.page_id().to_string()
} else {
search_result.title().to_string()
}
);
if let Err(error) = display_article(siv, article.clone()) {
log::warn!("{}", error);
siv.add_layer(
Dialog::info("A Problem occurred while displaying the article.\nCheck the logs for further information")
.title("Error")
.title_position(HAlign::Center)
);
log::info!("on_article_submit failed to finish");
return;
}
if let Some(toc) = article.toc() {
log::info!("displaying the table of contents");
ui::toc::add_table_of_contents(siv, toc);
}
log::info!("on_article_submit finished successfully");
}
pub fn on_link_submit(siv: &mut Cursive, target: String) {
log::info!(
"on_link_submit was called with the target link '{}'",
target
);
let target_human = {
let target = target.strip_prefix("/wiki/").unwrap_or(&target);
target.replace('_', " ")
};
log::info!("requesting confirmation from the user");
siv.add_layer(
Dialog::around(TextView::new(format!(
"Do you want to open the article '{}'?",
target_human
)))
.button("Yep", move |s| {
log::info!("on_link_submit - user said yes :) continuing...");
open_link(s, target.clone())
})
.button("Nope", move |s| {
log::info!("on_link_submit - said no :/ aborting...");
s.pop_layer();
}),
);
log::info!("on_link_submit finished successfully");
}
fn open_link(siv: &mut Cursive, target: String) {
log::debug!("open_link was called");
siv.pop_layer();
log::debug!("fetching the article");
let article = match ArticleBuilder::new(0, Some(target))
.build(&mut DefaultParser::new(&config::CONFIG.parser))
{
Ok(article) => article,
Err(error) => {
log::warn!("{:?}", error);
siv.add_layer(
Dialog::info("A Problem occurred while fetching the article.\nCheck the logs for further information")
.title("Error")
.title_position(HAlign::Center)
);
log::debug!("open_link failed to finish");
return;
}
};
log::debug!("displaying the article");
if let Err(error) = display_article(siv, article.clone()) {
log::warn!("{:?}", error);
siv.add_layer(
Dialog::info("A Problem occurred while displaying the article.\nCheck the logs for further information")
.title("Error")
.title_position(HAlign::Center)
);
log::debug!("open_link failed to finish");
return;
}
if let Some(toc) = article.toc() {
log::debug!("displaying the table of contents");
ui::toc::add_table_of_contents(siv, toc);
}
log::debug!("open_link finished successfully");
}
fn display_article(siv: &mut Cursive, article: Article) -> Result<()> {
log::debug!("display_article was called");
if siv
.find_name::<TextView>("search_results_preview")
.is_some()
{
siv.pop_layer();
log::debug!("removed the search_results_preview layer");
}
remove_view_from_layout(siv, "logo_view", "article_layout");
remove_view_from_layout(siv, "article_view", "article_layout");
remove_view_from_layout(siv, "toc_view", "article_layout");
let article_view = ArticleView::new(article);
log::debug!("created an instance of ArticleView");
let result = siv.call_on_name("article_layout", |view: &mut LinearLayout| {
view.insert_child(
0,
view_with_theme!(
config::CONFIG.theme.article_view,
Dialog::around(article_view.with_name("article_view").scrollable())
),
);
});
if result.is_none() {
log::debug!("display_article failed to finish");
bail!("Couldn't find the article layout");
}
log::debug!("added the ArticleView to the screen");
siv.focus_name("article_view").with_context(|| {
log::debug!("display_article failed to finish");
"Failed to focus the article view"
})?;
log::debug!("display_article finished successfully");
Ok(())
}