Compare commits

...

3 Commits

7 changed files with 69 additions and 7 deletions

View File

@ -41,6 +41,7 @@ pub enum Thread {
#[derive(Debug, SimpleObject)]
pub struct NewsPost {
pub thread_id: String,
pub is_read: bool,
pub slug: String,
pub site: String,
pub title: String,

View File

@ -9,7 +9,10 @@ use async_trait::async_trait;
use css_inline::{CSSInliner, InlineError, InlineOptions};
use linkify::{LinkFinder, LinkKind};
use log::{error, info, warn};
use lol_html::{element, errors::RewritingError, rewrite_str, text, RewriteStrSettings};
use lol_html::{
element, errors::RewritingError, html_content::ContentType, rewrite_str, text,
RewriteStrSettings,
};
use maplit::{hashmap, hashset};
use scraper::{error::SelectorErrorKind, Html, Selector};
use thiserror::Error;
@ -129,6 +132,36 @@ impl Transformer for InlineStyle {
}
}
/// Frame images will extract any alt or title tags on images and place them as labels below said
/// image.
struct FrameImages;
#[async_trait]
impl Transformer for FrameImages {
async fn transform(&self, link: &Option<Url>, html: &str) -> Result<String, TransformError> {
Ok(rewrite_str(
html,
RewriteStrSettings {
element_content_handlers: vec![element!("img[alt], img[title]", |el| {
info!("found image with alt or title {el:?}");
let src = el
.get_attribute("src")
.unwrap_or("https://placehold.co/600x400".to_string());
let alt = el.get_attribute("alt");
let title = el.get_attribute("title");
let mut frags = vec!["<figure>".to_string(), format!(r#"<img src="{src}">"#)];
alt.map(|t| frags.push(format!("<figcaption>Alt: {t}</figcaption>")));
title.map(|t| frags.push(format!("<figcaption>Title: {t}</figcaption>")));
frags.push("</figure>".to_string());
el.replace(&frags.join("\n"), ContentType::Html);
Ok(())
})],
..RewriteStrSettings::default()
},
)?)
}
}
struct AddOutlink;
#[async_trait]

View File

@ -15,7 +15,8 @@ use crate::{
compute_offset_limit,
error::ServerError,
graphql::{Body, Email, Html, Message, NewsPost, Tag, Thread, ThreadSummary},
AddOutlink, EscapeHtml, InlineStyle, SanitizeHtml, SlurpContents, StripHtml, Transformer,
AddOutlink, EscapeHtml, FrameImages, InlineStyle, SanitizeHtml, SlurpContents, StripHtml,
Transformer,
};
pub fn is_newsreader_search(query: &str) -> bool {
@ -193,6 +194,7 @@ pub async fn thread(pool: &PgPool, thread_id: String) -> Result<Thread, ServerEr
],
],
}),
Box::new(FrameImages),
Box::new(AddOutlink),
Box::new(EscapeHtml),
Box::new(InlineStyle),
@ -207,6 +209,7 @@ pub async fn thread(pool: &PgPool, thread_id: String) -> Result<Thread, ServerEr
}
}
let title = clean_title(&r.title.unwrap_or("NO TITLE".to_string())).await?;
let is_read = r.is_read.unwrap_or(false);
let timestamp = r
.date
.expect("post missing date")
@ -214,6 +217,7 @@ pub async fn thread(pool: &PgPool, thread_id: String) -> Result<Thread, ServerEr
.unix_timestamp();
Ok(Thread::News(NewsPost {
thread_id,
is_read,
slug,
site,
title,

View File

@ -878,6 +878,22 @@
}
}
},
{
"args": [],
"deprecationReason": null,
"description": null,
"isDeprecated": false,
"name": "isRead",
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "Boolean",
"ofType": null
}
}
},
{
"args": [],
"deprecationReason": null,

View File

@ -2,6 +2,7 @@ query ShowThreadQuery($threadId: String!) {
thread(threadId: $threadId) {
__typename ... on NewsPost{
threadId
isRead
slug
site
title

View File

@ -1131,9 +1131,7 @@ fn render_news_post_header(post: &ShowThreadQueryThreadOnNewsPost) -> Node<Msg>
let avatar: Option<String> = None;
//let avatar: Option<String> = Some(String::from("https://bulma.io/images/placeholders/64x64.png"));
let id = post.thread_id.clone();
// TODO: plumb this through
//let is_unread = has_unread(&msg.tags);
let is_unread = true;
let is_unread = !post.is_read;
let img = render_avatar(avatar, &from);
article![
C!["media"],

View File

@ -1,11 +1,11 @@
.body.site-saturday-morning-breakfast-cereal {
.body.news-post.site-saturday-morning-breakfast-cereal {
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
}
.body.site-slashdot i {
.body.news-post.site-slashdot i {
border-left: 2px solid #ddd;
display: block;
font-style: normal !important;
@ -13,3 +13,12 @@
margin-top: 1em;
padding-left: 1em;
}
.body.news-post em {
margin: inherit !important;
padding: inherit !important;
font-weight: inherit !important;
border: inherit !important;
display: inline !important;
color: inherit !important;
}