Skip to content

Commit

Permalink
implement link opening
Browse files Browse the repository at this point in the history
- press 'Enter' to open a selected link
- currently, no popup opens, the link is automatically opened (ESC to
  pop the page and return)
  • Loading branch information
Builditluc committed May 26, 2024
1 parent fb50df5 commit 88077e6
Show file tree
Hide file tree
Showing 9 changed files with 496 additions and 86 deletions.
29 changes: 29 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

30 changes: 18 additions & 12 deletions src/components/page.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ use ratatui::{
};
use tracing::{debug, info, warn};
use wiki_api::{
document::Data,
page::{Page, Section},
document::{Data, Node},
page::{Link, Page, Section},
};

use crate::{
Expand Down Expand Up @@ -218,7 +218,7 @@ impl PageComponent {
.nth(0)
.unwrap()
.descendants()
.find(|node| matches!(node.data(), &Data::WikiLink { .. }));
.find(|node| matches!(node.data(), &Data::Link(_)));

if let Some(selectable_node) = selectable_node {
let first_index = selectable_node.index();
Expand All @@ -241,9 +241,7 @@ impl PageComponent {
.nth(0)
.unwrap()
.descendants()
.filter(|node| {
matches!(node.data(), &Data::WikiLink { .. }) && node.index() < self.selected.0
})
.filter(|node| matches!(node.data(), &Data::Link(_)) && node.index() < self.selected.0)
.last();

if let Some(selectable_node) = selectable_node {
Expand All @@ -267,9 +265,7 @@ impl PageComponent {
.nth(0)
.unwrap()
.descendants()
.find(|node| {
matches!(node.data(), &Data::WikiLink { .. }) && self.selected.1 < node.index()
});
.find(|node| matches!(node.data(), &Data::Link(_)) && self.selected.1 < node.index());

if let Some(selectable_node) = selectable_node {
let first_index = selectable_node.index();
Expand All @@ -292,9 +288,7 @@ impl PageComponent {
.nth(0)
.unwrap()
.descendants()
.filter(|node| {
matches!(node.data(), &Data::WikiLink { .. }) && node.index() > self.selected.1
})
.filter(|node| matches!(node.data(), &Data::Link(_)) && node.index() > self.selected.1)
.last();

if let Some(selectable_node) = selectable_node {
Expand All @@ -307,6 +301,17 @@ impl PageComponent {
}
}

fn open_link(&self) -> ActionResult {
let index = self.selected.0;
let node = Node::new(&self.page.content, index).unwrap();
let data = node.data().to_owned();

match data {
Data::Link(Link::Internal(link_data)) => Action::LoadPage(link_data.page).into(),
_ => ActionResult::consumed(),
}
}

fn resize(&mut self, width: u16, height: u16) {
self.viewport.width = width;
self.viewport.height = height;
Expand Down Expand Up @@ -405,6 +410,7 @@ impl Component for PageComponent {
}
KeyCode::Left => Action::Page(PageAction::SelectPrevLink).into(),
KeyCode::Right => Action::Page(PageAction::SelectNextLink).into(),
KeyCode::Enter => self.open_link(),
_ => ActionResult::Ignored,
}
}
Expand Down
6 changes: 5 additions & 1 deletion src/page_loader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,11 @@ impl PageLoader {
pub fn load_page(&self, title: String) {
let page_request = Page::builder()
.page(title)
.properties(vec![Property::Text, Property::Sections, Property::LangLinks])
.properties(vec![
Property::Text,
Property::Sections,
Property::LangLinks,
])
.endpoint(self.endpoint.clone())
.language(self.language.clone());

Expand Down
16 changes: 15 additions & 1 deletion src/renderer/default_renderer.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
use ratatui::style::{Color, Modifier, Style};
use textwrap::wrap_algorithms::{wrap_optimal_fit, Penalties};
use tracing::warn;
use wiki_api::document::{Data, Document, HeaderKind, Node};
use wiki_api::{
document::{Data, Document, HeaderKind, Node},
page::Link,
};

use crate::renderer::Word;

Expand Down Expand Up @@ -447,6 +450,16 @@ impl<'a> Renderer {
self.add_whitespace();
}

fn render_link(&mut self, node: Node<'a>, link: Link) {
match link {
Link::Internal(_) => self.render_wiki_link(node),
Link::Anchor(_) => self.render_wiki_link(node),
Link::RedLink(_) => self.render_red_link(node),
Link::External(_) => self.render_external_link(node),
Link::ExternalToInternal(_) => self.render_external_link(node),
}
}

fn render_wiki_link(&mut self, node: Node<'a>) {
self.set_text_fg(Color::Blue);
self.render_children(node);
Expand Down Expand Up @@ -508,6 +521,7 @@ impl<'a> Renderer {
Data::DerscriptionListDescription => self.render_description_list_description(node),
Data::Bold => self.render_bold(node),
Data::Italic => self.render_italic(node),
Data::Link(link) => self.render_link(node, link.clone()),
Data::WikiLink { href: _, title: _ } => self.render_wiki_link(node),
Data::RedLink { title: _ } => self.render_red_link(node),
Data::MediaLink { href: _, title: _ } => self.render_media_link(node),
Expand Down
2 changes: 2 additions & 0 deletions wiki-api/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,10 @@ scraper = "0.17.1"
serde = "1.0.188"
serde_json = "1.0.105"
serde_repr = "0.1.16"
snafu = "0.8.3"
tracing = "0.1.37"
url = { version = "2.4.1", features = ["serde"] }
urlencoding = "2.1.3"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

Expand Down
3 changes: 3 additions & 0 deletions wiki-api/src/document.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
use serde_repr::Deserialize_repr;

use crate::page::Link;

#[derive(Clone, PartialEq, Eq)]
pub struct Document {
pub nodes: Vec<Raw>,
Expand Down Expand Up @@ -59,6 +61,7 @@ pub enum Data {
Bold,
Italic,

Link(Link),
WikiLink {
href: String,
title: Option<String>,
Expand Down
6 changes: 4 additions & 2 deletions wiki-api/src/page.rs
Original file line number Diff line number Diff line change
Expand Up @@ -395,12 +395,14 @@ impl<I, P> PageBuilder<I, P, WithEndpoint, WithLanguage> {
.map(|x| x as usize)
.ok_or_else(|| anyhow!("missing the pageid"))?;

let endpoint = self.endpoint.0;
let language = self.language.0;
let content = res_json
.get("parse")
.and_then(|x| x.get("text"))
.and_then(|x| x.as_str())
.map(|x| {
let parser = WikipediaParser::parse_document(x);
let parser = WikipediaParser::parse_document(x, endpoint, language.clone());
Document {
nodes: parser.nodes(),
}
Expand Down Expand Up @@ -470,7 +472,7 @@ impl<I, P> PageBuilder<I, P, WithEndpoint, WithLanguage> {
title,
pageid,
content,
language: self.language.0,
language,
language_links,
sections,
revision_id,
Expand Down
Loading

0 comments on commit 88077e6

Please sign in to comment.