Skip to content

Commit fef3aa3

Browse files
committed
Refactor draw_ctx into text_extensions
1 parent 0c08ecb commit fef3aa3

File tree

6 files changed

+76
-93
lines changed

6 files changed

+76
-93
lines changed

src/common/mod.rs

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -92,13 +92,6 @@ pub struct HistoryItem {
9292
pub scroll_progress: f64,
9393
}
9494

95-
// This struct contains all the data needed to fetch and render the data of a page
96-
pub struct RequestCtx {
97-
pub gemini_client: gemini::Client,
98-
pub draw_ctx: crate::draw_ctx::DrawCtx,
99-
pub url: Url,
100-
}
101-
10295
#[async_trait(?Send)]
10396
pub trait LossyTextRead {
10497
async fn read_line_lossy(&mut self, mut buf: &mut String) -> std::io::Result<usize>;

src/main.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ mod build_config;
1414
mod common;
1515
mod config;
1616
mod download_page;
17-
mod draw_ctx;
17+
mod text_extensions;
1818
mod gemini;
1919
mod input_page;
2020
mod macros;

src/tab.rs

Lines changed: 61 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,11 @@ use std::marker::PhantomData;
1919
use std::pin::Pin;
2020
use std::rc::Rc;
2121
use url::Url;
22+
use gtk::gdk;
2223

2324
use crate::common;
24-
use crate::common::{glibctx, HistoryItem, LossyTextRead, PageElement, RequestCtx};
25-
use crate::draw_ctx::DrawCtx;
25+
use crate::common::{glibctx, HistoryItem, LossyTextRead, PageElement};
26+
use crate::text_extensions::Gemini as GeminiTextExt;
2627
use crate::gemini;
2728

2829
#[derive(Clone, Debug, glib::Boxed, Default)]
@@ -39,7 +40,7 @@ pub mod imp {
3940
#[properties(wrapper_type = super::Tab)]
4041
pub struct Tab {
4142
pub(crate) gemini_client: RefCell<gemini::Client>,
42-
pub(crate) draw_ctx: RefCell<Option<DrawCtx>>,
43+
pub(crate) gemini_text_ext: RefCell<Option<GeminiTextExt>>,
4344
pub(crate) history: RefCell<Vec<HistoryItem>>,
4445
pub(crate) current_hi: RefCell<Option<usize>>,
4546
#[template_child]
@@ -149,38 +150,30 @@ impl Tab {
149150
imp.text_view
150151
.add_controller(imp.motion_ctrl.borrow().as_ref().unwrap());
151152

152-
imp.draw_ctx
153-
.replace(Some(DrawCtx::new(imp.text_view.clone(), config)));
153+
imp.gemini_text_ext
154+
.replace(Some(GeminiTextExt::new(imp.text_view.clone(), config)));
154155

155156
this.bind_signals();
156157
this
157158
}
158-
fn build_request_ctx(&self, url: Url) -> RequestCtx {
159-
let imp = self.imp();
160-
RequestCtx {
161-
draw_ctx: imp.draw_ctx.borrow().clone().unwrap(),
162-
gemini_client: imp.gemini_client.borrow().clone(),
163-
url,
164-
}
165-
}
166159
pub fn handle_click(&self, x: f64, y: f64) -> Result<()> {
167160
let imp = self.imp();
168-
let draw_ctx = imp.draw_ctx.borrow();
169-
let text_view = &draw_ctx.as_ref().unwrap().text_view;
161+
let gemini_text_ext = imp.gemini_text_ext.borrow();
162+
let text_view = &gemini_text_ext.as_ref().unwrap().text_view;
170163
let has_selection = text_view.buffer().has_selection();
171164
if has_selection {
172165
return Ok(());
173166
}
174-
let link = Self::extract_linkhandler(draw_ctx.as_ref().unwrap(), x, y)?;
167+
let link = Self::extract_linkhandler(gemini_text_ext.as_ref().unwrap(), x, y)?;
175168
let url = self.parse_link(&link)?;
176169
self.spawn_open_url(url);
177170
Ok(())
178171
}
179172
fn handle_right_click(&self, x: f64, y: f64) -> Result<()> {
180173
let imp = self.imp();
181-
let draw_ctx = imp.draw_ctx.borrow();
182-
let text_view = &draw_ctx.as_ref().unwrap().text_view;
183-
let link = Self::extract_linkhandler(draw_ctx.as_ref().unwrap(), x, y)?;
174+
let gemini_text_ext = imp.gemini_text_ext.borrow();
175+
let text_view = &gemini_text_ext.as_ref().unwrap().text_view;
176+
let link = Self::extract_linkhandler(gemini_text_ext.as_ref().unwrap(), x, y)?;
184177
let link = self.parse_link(&link)?;
185178
let link_variant = link.as_str().to_variant();
186179

@@ -198,23 +191,21 @@ impl Tab {
198191
}
199192
fn handle_motion(&self, x: f64, y: f64) -> Result<()> {
200193
let imp = self.imp();
201-
let draw_ctx = imp.draw_ctx.borrow();
202-
let draw_ctx = draw_ctx.as_ref().unwrap();
203-
let link = Self::extract_linkhandler(draw_ctx, x, y);
194+
let gemini_text_ext = imp.gemini_text_ext.borrow();
195+
let gemini_text_ext = gemini_text_ext.as_ref().unwrap();
196+
let link = Self::extract_linkhandler(gemini_text_ext, x, y);
204197
match link {
205198
Ok(_) => {
206-
draw_ctx.text_view.set_cursor_from_name(Some("pointer"));
199+
gemini_text_ext.text_view.set_cursor_from_name(Some("pointer"));
207200
}
208201
Err(_) => {
209-
draw_ctx.text_view.set_cursor_from_name(Some("text"));
202+
gemini_text_ext.text_view.set_cursor_from_name(Some("text"));
210203
}
211204
}
212205

213206
Ok(())
214207
}
215208
pub fn spawn_open_url(&self, url: Url) {
216-
let imp = self.imp();
217-
218209
let i = self.add_to_history(HistoryItem {
219210
url: url.clone(),
220211
cache: Default::default(),
@@ -272,17 +263,15 @@ impl Tab {
272263
*imp.url.borrow_mut() = url.to_string();
273264
self.notify("url");
274265

275-
let mut req_ctx = self.build_request_ctx(url.clone());
276-
277266
let this = self.clone();
278267
let fut = async move {
279-
let cache = match this.send_request(&mut req_ctx).await {
268+
let cache = match this.send_request(url.clone()).await {
280269
Ok(Some(cache)) => {
281270
info!("Page loaded, can be cached ({})", url.clone());
282271
Some(cache)
283272
}
284273
Ok(_) => {
285-
info!("Page loaded ({})", url.clone());
274+
info!("Page loaded ({})", &url);
286275
None
287276
}
288277
Err(e) => {
@@ -306,7 +295,7 @@ impl Tab {
306295
}
307296
fn open_cached(&self, url: Url, cache: Vec<u8>) -> impl Future<Output = ()> {
308297
let imp = self.imp();
309-
let mut draw_ctx = imp.draw_ctx.borrow().clone().unwrap();
298+
let mut gemini_text_ext = imp.gemini_text_ext.borrow().clone().unwrap();
310299

311300
*self.imp().progress.borrow_mut() = 0.0;
312301
self.notify("progress");
@@ -320,7 +309,7 @@ impl Tab {
320309
let this = self.clone();
321310
async move {
322311
let buf = BufReader::new(&*cache);
323-
draw_ctx.clear();
312+
gemini_text_ext.clear();
324313
let res = this.display_gemini(buf).await;
325314
match res {
326315
Ok(_) => {
@@ -409,8 +398,8 @@ impl Tab {
409398
}),
410399
);
411400
}
412-
fn extract_linkhandler(draw_ctx: &DrawCtx, x: f64, y: f64) -> Result<String> {
413-
let text_view = &draw_ctx.text_view;
401+
fn extract_linkhandler(gemini_text_ext: &GeminiTextExt, x: f64, y: f64) -> Result<String> {
402+
let text_view = &gemini_text_ext.text_view;
414403
let (x, y) =
415404
text_view.window_to_buffer_coords(gtk::TextWindowType::Widget, x as i32, y as i32);
416405
let iter = text_view
@@ -419,13 +408,12 @@ impl Tab {
419408

420409
iter.tags()
421410
.iter()
422-
.find_map(DrawCtx::linkhandler)
411+
.find_map(GeminiTextExt::linkhandler)
423412
.cloned()
424413
.ok_or(anyhow::Error::msg("Clicked text doesn't have a link tag"))
425414
}
426-
async fn open_file_url(&self, req: &mut RequestCtx) -> Result<()> {
427-
let path = req
428-
.url
415+
async fn open_file_url(&self, url: Url) -> Result<()> {
416+
let path = url
429417
.to_file_path()
430418
.map_err(|_| anyhow::Error::msg("Can't convert link to file path"))?;
431419

@@ -437,32 +425,33 @@ impl Tab {
437425
this.display_gemini(lines).await?;
438426
}
439427
_ => {
440-
Self::display_text(&mut req.draw_ctx, lines).await?;
428+
this.display_text(lines).await?;
441429
}
442430
}
443431
Ok(())
444432
}
445-
async fn send_request(&self, req: &mut RequestCtx) -> Result<Option<Vec<u8>>> {
446-
req.draw_ctx.clear();
447-
match req.url.scheme() {
433+
async fn send_request(&self, url: Url) -> Result<Option<Vec<u8>>> {
434+
self.imp().gemini_text_ext.borrow_mut().as_mut().unwrap().clear();
435+
match url.scheme() {
448436
"about" => {
449437
let reader = futures::io::BufReader::new(common::ABOUT_PAGE.as_bytes());
450438
self.display_gemini(reader).await?;
451439
Ok(None)
452440
}
453441
"file" => {
454-
self.open_file_url(req).await?;
442+
self.open_file_url(url).await?;
455443
Ok(None)
456444
}
457-
"gemini" => self.open_gemini_url(req).await,
445+
"gemini" => self.open_gemini_url(url).await,
458446
_ => {
459-
self.display_url_confirmation(&req.url);
447+
self.display_url_confirmation(&url);
460448
Ok(None)
461449
}
462450
}
463451
}
464-
async fn open_gemini_url(&self, req: &mut RequestCtx) -> anyhow::Result<Option<Vec<u8>>> {
465-
let res: gemini::Response = req.gemini_client.fetch(req.url.as_str()).await?;
452+
async fn open_gemini_url(&self, url: Url) -> anyhow::Result<Option<Vec<u8>>> {
453+
let imp = self.imp();
454+
let res: gemini::Response = imp.gemini_client.borrow().fetch(url.as_str()).await?;
466455

467456
use gemini::Status::*;
468457
let meta = res.meta().to_owned();
@@ -472,7 +461,7 @@ impl Tab {
472461
let this = self.clone();
473462
let res = match status {
474463
Input(_) => {
475-
self.display_input(req.url.clone(), &meta);
464+
self.display_input(url.clone(), &meta);
476465
None
477466
}
478467
Success(_) => {
@@ -482,10 +471,10 @@ impl Tab {
482471
let res = this.display_gemini(buffered).await?;
483472
Some(res)
484473
} else if meta.contains("text") {
485-
Self::display_text(&mut req.draw_ctx, buffered).await?;
474+
self.display_text(buffered).await?;
486475
None
487476
} else {
488-
self.display_download(req.url.clone(), buffered).await?;
477+
self.display_download(url.clone(), buffered).await?;
489478
None
490479
}
491480
}
@@ -596,19 +585,21 @@ impl Tab {
596585
Ok(())
597586
}
598587
async fn display_text(
599-
draw_ctx: &mut DrawCtx,
588+
&self,
600589
mut stream: impl AsyncBufRead + Unpin,
601590
) -> anyhow::Result<()> {
591+
let gemini_text_ext = self.imp().gemini_text_ext.borrow();
592+
let gemini_text_ext = gemini_text_ext.as_ref().unwrap();
602593
let mut line = String::with_capacity(1024);
603594
loop {
604595
line.clear();
605596
let n = stream.read_line_lossy(&mut line).await?;
606597
if n == 0 {
607598
break Ok(());
608599
}
609-
let text_iter = &mut draw_ctx.text_buffer.end_iter();
610-
draw_ctx.insert_paragraph(text_iter, &line);
611-
draw_ctx.insert_paragraph(text_iter, "\n");
600+
let text_iter = &mut gemini_text_ext.text_buffer.end_iter();
601+
gemini_text_ext.insert_paragraph(text_iter, &line);
602+
gemini_text_ext.insert_paragraph(text_iter, "\n");
612603
}
613604
}
614605

@@ -665,10 +656,10 @@ impl Tab {
665656
mut reader: T,
666657
) -> anyhow::Result<Vec<u8>> {
667658
let imp = self.imp();
668-
let mut draw_ctx = imp.draw_ctx.borrow().clone().unwrap();
659+
let mut gemini_text_ext = imp.gemini_text_ext.borrow().clone().unwrap();
669660

670661
let mut parser = gemini::Parser::new();
671-
let mut text_iter = draw_ctx.text_buffer.end_iter();
662+
let mut text_iter = gemini_text_ext.text_buffer.end_iter();
672663

673664
let mut preformatted = String::new();
674665
let mut data = String::with_capacity(1024);
@@ -691,15 +682,15 @@ impl Tab {
691682
// preformatted text is handled different hoping to add scrollbars for it,
692683
// in the future, maybe
693684
if !preformatted.is_empty() {
694-
draw_ctx.insert_preformatted(&mut text_iter, &preformatted);
685+
gemini_text_ext.insert_preformatted(&mut text_iter, &preformatted);
695686
preformatted.clear();
696687
}
697688
match token {
698689
PageElement::Text(line) => {
699-
draw_ctx.insert_paragraph(&mut text_iter, &line);
690+
gemini_text_ext.insert_paragraph(&mut text_iter, &line);
700691
}
701692
PageElement::Heading(line) => {
702-
draw_ctx.insert_heading(&mut text_iter, &line);
693+
gemini_text_ext.insert_heading(&mut text_iter, &line);
703694
if !title_updated {
704695
title_updated = true;
705696
imp.title
@@ -708,10 +699,10 @@ impl Tab {
708699
}
709700
}
710701
PageElement::Quote(line) => {
711-
draw_ctx.insert_quote(&mut text_iter, &line);
702+
gemini_text_ext.insert_quote(&mut text_iter, &line);
712703
}
713704
PageElement::Empty => {
714-
draw_ctx.insert_paragraph(&mut text_iter, "\n");
705+
gemini_text_ext.insert_paragraph(&mut text_iter, "\n");
715706
}
716707
PageElement::Link(url, label) => {
717708
let link_char = if let Ok(true) = self
@@ -723,12 +714,20 @@ impl Tab {
723714
"⇗"
724715
};
725716
let label = format!("{link_char} {}", label.as_deref().unwrap_or(&url));
726-
draw_ctx.insert_link(&mut text_iter, url.clone(), Some(&label));
717+
gemini_text_ext.insert_link(&mut text_iter, url.clone(), Some(&label));
727718
}
728719
PageElement::Preformatted(_) => unreachable!("handled before"),
729720
}
730721
}
731722
}
732723
Ok(data.into_bytes())
733724
}
725+
pub fn set_link_color(&self, rgba: &gdk::RGBA) {
726+
self.imp()
727+
.gemini_text_ext
728+
.borrow()
729+
.as_ref()
730+
.unwrap()
731+
.set_link_color(rgba);
732+
}
734733
}

0 commit comments

Comments
 (0)