web & server: finish initial tailwind rewrite
This commit is contained in:
parent
70fb635eda
commit
ee93d725ba
@ -1,8 +0,0 @@
|
||||
pre {
|
||||
background-color: var(--color-bg);
|
||||
color: var(--color-text);
|
||||
}
|
||||
|
||||
code {
|
||||
background-color: var(--color-bg-secondary);
|
||||
}
|
||||
@ -117,26 +117,7 @@ struct InlineRemoteStyle<'a> {
|
||||
#[async_trait]
|
||||
impl<'a> Transformer for InlineRemoteStyle<'a> {
|
||||
async fn transform(&self, _: &Option<Url>, html: &str) -> Result<String, TransformError> {
|
||||
let css = concat!(
|
||||
"/* chrome-default.css */\n",
|
||||
include_str!("chrome-default.css"),
|
||||
"\n/* mvp.css */\n",
|
||||
include_str!("mvp.css"),
|
||||
"\n/* Xinu Specific overrides */\n",
|
||||
include_str!("custom.css"),
|
||||
);
|
||||
let inline_opts = InlineOptions {
|
||||
//inline_style_tags: true,
|
||||
//keep_style_tags: false,
|
||||
//keep_link_tags: true,
|
||||
base_url: self.base_url.clone(),
|
||||
//load_remote_stylesheets: true,
|
||||
//preallocate_node_capacity: 32,
|
||||
..InlineOptions::default()
|
||||
};
|
||||
|
||||
//info!("HTML:\n{html}");
|
||||
info!("base_url: {:#?}", self.base_url);
|
||||
Ok(
|
||||
match CSSInliner::options()
|
||||
.base_url(self.base_url.clone())
|
||||
@ -160,10 +141,10 @@ impl Transformer for InlineStyle {
|
||||
let css = concat!(
|
||||
"/* chrome-default.css */\n",
|
||||
include_str!("chrome-default.css"),
|
||||
"\n/* mvp.css */\n",
|
||||
include_str!("mvp.css"),
|
||||
"\n/* Xinu Specific overrides */\n",
|
||||
include_str!("custom.css"),
|
||||
//"\n/* mvp.css */\n",
|
||||
//include_str!("mvp.css"),
|
||||
//"\n/* Xinu Specific overrides */\n",
|
||||
//include_str!("custom.css"),
|
||||
);
|
||||
let inline_opts = InlineOptions {
|
||||
inline_style_tags: true,
|
||||
@ -288,13 +269,25 @@ impl SlurpContents {
|
||||
|
||||
#[async_trait]
|
||||
impl Transformer for SlurpContents {
|
||||
fn should_run(&self, link: &Option<Url>, _: &str) -> bool {
|
||||
fn should_run(&self, link: &Option<Url>, html: &str) -> bool {
|
||||
let mut will_slurp = false;
|
||||
if let Some(link) = link {
|
||||
return self.get_selectors(link).is_some();
|
||||
will_slurp = self.get_selectors(link).is_some();
|
||||
}
|
||||
false
|
||||
if !will_slurp && self.inline_css {
|
||||
return InlineStyle {}.should_run(link, html);
|
||||
}
|
||||
will_slurp
|
||||
}
|
||||
async fn transform(&self, link: &Option<Url>, html: &str) -> Result<String, TransformError> {
|
||||
if let Some(test_link) = link {
|
||||
// If SlurpContents is configured for inline CSS, but no
|
||||
// configuration found for this site, use the local InlineStyle
|
||||
// transform.
|
||||
if self.inline_css && self.get_selectors(test_link).is_none() {
|
||||
return InlineStyle {}.transform(link, html).await;
|
||||
}
|
||||
}
|
||||
let Some(link) = link else {
|
||||
return Ok(html.to_string());
|
||||
};
|
||||
@ -303,7 +296,6 @@ impl Transformer for SlurpContents {
|
||||
};
|
||||
let cacher = self.cacher.lock().await;
|
||||
let body = if let Some(body) = cacher.get(link.as_str()) {
|
||||
info!("cache hit for {link}");
|
||||
String::from_utf8_lossy(&body).to_string()
|
||||
} else {
|
||||
let body = reqwest::get(link.as_str()).await?.text().await?;
|
||||
@ -315,8 +307,17 @@ impl Transformer for SlurpContents {
|
||||
let body = if self.inline_css {
|
||||
let inner_body = Arc::clone(&body);
|
||||
let res = tokio::task::spawn_blocking(move || {
|
||||
let css = concat!(
|
||||
"/* chrome-default.css */\n",
|
||||
include_str!("chrome-default.css"),
|
||||
"\n/* vars.css */\n",
|
||||
include_str!("../../web/static/vars.css"),
|
||||
//"\n/* Xinu Specific overrides */\n",
|
||||
//include_str!("custom.css"),
|
||||
);
|
||||
let res = CSSInliner::options()
|
||||
.base_url(base_url)
|
||||
.extra_css(Some(std::borrow::Cow::Borrowed(css)))
|
||||
.build()
|
||||
.inline(&inner_body);
|
||||
|
||||
|
||||
@ -15,9 +15,8 @@ use crate::{
|
||||
config::Config,
|
||||
error::ServerError,
|
||||
graphql::{Corpus, NewsPost, Tag, Thread, ThreadSummary},
|
||||
thread_summary_from_row, AddOutlink, EscapeHtml, FrameImages, InlineRemoteStyle, Query,
|
||||
SanitizeHtml, SlurpContents, ThreadSummaryRecord, Transformer, NEWSREADER_TAG_PREFIX,
|
||||
NEWSREADER_THREAD_PREFIX,
|
||||
thread_summary_from_row, AddOutlink, FrameImages, Query, SanitizeHtml, SlurpContents,
|
||||
ThreadSummaryRecord, Transformer, NEWSREADER_TAG_PREFIX, NEWSREADER_THREAD_PREFIX,
|
||||
};
|
||||
|
||||
pub fn is_newsreader_query(query: &Query) -> bool {
|
||||
@ -196,8 +195,7 @@ pub async fn thread(
|
||||
let body_tranformers: Vec<Box<dyn Transformer>> = vec![
|
||||
Box::new(SlurpContents {
|
||||
cacher,
|
||||
// TODO: make this true when bulma is finally removed
|
||||
inline_css: false,
|
||||
inline_css: true,
|
||||
site_selectors: hashmap![
|
||||
"atmeta.com".to_string() => vec![
|
||||
Selector::parse("div.entry-content").unwrap(),
|
||||
@ -239,6 +237,14 @@ pub async fn thread(
|
||||
Selector::parse("span.story-byline").unwrap(),
|
||||
Selector::parse("div.p").unwrap(),
|
||||
],
|
||||
"theonion.com".to_string() => vec![
|
||||
// Single cartoon
|
||||
Selector::parse("article > div > div > figure").unwrap(),
|
||||
// Image at top of article
|
||||
Selector::parse("article > header > div > div > figure").unwrap(),
|
||||
// Article body
|
||||
Selector::parse("article .entry-content > *").unwrap(),
|
||||
],
|
||||
"trofi.github.io".to_string() => vec![
|
||||
Selector::parse("#content").unwrap(),
|
||||
],
|
||||
|
||||
@ -13,7 +13,9 @@
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Poppins:wght@700&display=swap" rel="stylesheet">
|
||||
<!-- <link data-trunk rel="css" href="static/site-specific.css" /> -->
|
||||
<link data-trunk rel="css" href="static/vars.css" />
|
||||
<link data-trunk rel="tailwind-css" href="./src/tailwind.css" />
|
||||
<link data-trunk rel="css" href="static/overrides.css" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
@ -86,7 +86,13 @@ pub fn view(model: &Model) -> Node<Msg> {
|
||||
} => search_results(&query, results.as_slice(), *count, pager, selected_threads),
|
||||
};
|
||||
div![
|
||||
C!["flex", "flex-wrap-reverse", "bg-black", "text-white"],
|
||||
C![
|
||||
"flex",
|
||||
"flex-wrap-reverse",
|
||||
"bg-black",
|
||||
"text-white",
|
||||
"lg:flex-nowrap"
|
||||
],
|
||||
div![
|
||||
C!["w-full", "lg:w-48", "flex-none", "flex", "flex-col"],
|
||||
tags(model),
|
||||
@ -190,6 +196,7 @@ fn set_title(title: &str) {
|
||||
seed::document().set_title(&format!("lb: {}", title));
|
||||
}
|
||||
|
||||
// TODO: unifiy tags_chiclet, removable_tags_chiclet, and tags inside news_post()
|
||||
fn tags_chiclet(tags: &[String], is_mobile: bool) -> impl Iterator<Item = Node<Msg>> + '_ {
|
||||
tags.iter().map(move |tag| {
|
||||
let hex = compute_color(tag);
|
||||
@ -1147,8 +1154,6 @@ pub fn tags(model: &Model) -> Node<Msg> {
|
||||
]
|
||||
}
|
||||
fn news_post(post: &ShowThreadQueryThreadOnNewsPost, content_el: &ElRef<HtmlElement>) -> Node<Msg> {
|
||||
// TODO remove and replace with CSS styling
|
||||
let show_icon_text = true;
|
||||
let subject = &post.title;
|
||||
set_title(subject);
|
||||
let read_thread_id = post.thread_id.clone();
|
||||
@ -1156,94 +1161,68 @@ fn news_post(post: &ShowThreadQueryThreadOnNewsPost, content_el: &ElRef<HtmlElem
|
||||
fn tag(tag: String, is_mobile: bool) -> Node<Msg> {
|
||||
let hex = compute_color(&tag);
|
||||
let style = style! {St::BackgroundColor=>hex};
|
||||
let classes = C!["NOTPORTED", "tag", IF!(is_mobile => "is-small")];
|
||||
let attrs = attrs! {
|
||||
At::Href => urls::search(&format!("tag:{tag}"), 0)
|
||||
};
|
||||
let tag = tag.clone();
|
||||
div![
|
||||
C![
|
||||
"NOTPORTED",
|
||||
"message-tags",
|
||||
"field",
|
||||
"is-grouped",
|
||||
"is-grouped-multiline"
|
||||
],
|
||||
div![
|
||||
C!["NOTPORTED", "control"],
|
||||
div![
|
||||
C!["NOTPORTED", "tags", "has-addons"],
|
||||
a![
|
||||
classes,
|
||||
attrs,
|
||||
style,
|
||||
match tag.as_str() {
|
||||
"attachment" => span!["📎"],
|
||||
"replied" => span![i![C!["NOTPORTED", "fa-solid", "fa-reply"]]],
|
||||
_ => span![&tag],
|
||||
},
|
||||
ev(Ev::Click, move |_| Msg::FrontPageRequest {
|
||||
query: format!("tag:{tag}"),
|
||||
after: None,
|
||||
before: None,
|
||||
first: None,
|
||||
last: None,
|
||||
})
|
||||
]
|
||||
]
|
||||
]
|
||||
a![
|
||||
attrs,
|
||||
span![C![&tw_classes::TAG], style, &tag],
|
||||
ev(Ev::Click, move |_| Msg::FrontPageRequest {
|
||||
query: format!("tag:{tag}"),
|
||||
after: None,
|
||||
before: None,
|
||||
first: None,
|
||||
last: None,
|
||||
})
|
||||
]
|
||||
}
|
||||
|
||||
div![
|
||||
C!["NOTPORTED", "thread"],
|
||||
h3![C!["NOTPORTED", "is-size-5"], subject],
|
||||
tag(format!("News/{}", post.slug), false),
|
||||
C!["lg:p-4", "max-w-4xl"],
|
||||
div![
|
||||
C!["NOTPORTED", "level", "is-mobile"],
|
||||
C!["p-4", "lg:p-0"],
|
||||
h3![C!["text-xl"], subject],
|
||||
span![tag(format!("News/{}", post.slug), false)],
|
||||
div![
|
||||
C!["NOTPORTED", "level-item"],
|
||||
C!["pt-4", "gap-2", "flex", "justify-around"],
|
||||
div![
|
||||
C!["NOTPORTED", "buttons", "has-addons"],
|
||||
button![
|
||||
C!["NOTPORTED", "button", "mark-read"],
|
||||
C![&tw_classes::BUTTON, "rounded-r-none"],
|
||||
attrs! {At::Title => "Mark as read"},
|
||||
span![
|
||||
C!["NOTPORTED", "icon", "is-small"],
|
||||
i![C!["NOTPORTED", "far", "fa-envelope-open"]]
|
||||
],
|
||||
IF!(show_icon_text=>span!["Read"]),
|
||||
span![i![C!["far", "fa-envelope-open"]]],
|
||||
span![C!["pl-2", "hidden", "md:inline"], "Read"],
|
||||
ev(Ev::Click, move |_| Msg::MultiMsg(vec![
|
||||
Msg::SetUnread(read_thread_id, false),
|
||||
Msg::GoToSearchResults
|
||||
])),
|
||||
],
|
||||
button![
|
||||
C!["NOTPORTED", "button", "mark-unread"],
|
||||
C![&tw_classes::BUTTON, "rounded-l-none"],
|
||||
attrs! {At::Title => "Mark as unread"},
|
||||
span![
|
||||
C!["NOTPORTED", "icon", "is-small"],
|
||||
i![C!["NOTPORTED", "far", "fa-envelope"]]
|
||||
],
|
||||
IF!(show_icon_text=>span!["Unread"]),
|
||||
span![i![C!["far", "fa-envelope"]]],
|
||||
span![C!["pl-2", "hidden", "md:inline"], "Unread"],
|
||||
ev(Ev::Click, move |_| Msg::MultiMsg(vec![
|
||||
Msg::SetUnread(unread_thread_id, true),
|
||||
Msg::GoToSearchResults
|
||||
])),
|
||||
],
|
||||
],
|
||||
// Placeholder for symmetry with email view that has Spam button
|
||||
div![],
|
||||
],
|
||||
// This would be the holder for spam buttons on emails, needed to keep layout
|
||||
// consistent
|
||||
div![C!["NOTPORTED", "level-item"], div![]]
|
||||
],
|
||||
div![
|
||||
C!["NOTPORTED", "message"],
|
||||
div![C!["NOTPORTED", "header"], render_news_post_header(&post)],
|
||||
C!["lg:mt-4"],
|
||||
div![render_news_post_header(&post)],
|
||||
div![
|
||||
C![
|
||||
"NOTPORTED",
|
||||
"body",
|
||||
"bg-white",
|
||||
"text-black",
|
||||
"p-4",
|
||||
"lg:mb-4",
|
||||
"min-w-full",
|
||||
"overflow-x-auto",
|
||||
"news-post",
|
||||
format!("site-{}", post.slug)
|
||||
],
|
||||
@ -1251,12 +1230,6 @@ fn news_post(post: &ShowThreadQueryThreadOnNewsPost, content_el: &ElRef<HtmlElem
|
||||
raw![&post.body]
|
||||
]
|
||||
],
|
||||
/* TODO(wathiede): plumb in orignal id
|
||||
a![
|
||||
attrs! {At::Href=>api::original(&thread_node.0.as_ref().expect("message missing").id)},
|
||||
"Original"
|
||||
],
|
||||
*/
|
||||
click_to_top(),
|
||||
]
|
||||
}
|
||||
@ -1289,7 +1262,7 @@ fn render_news_post_header(post: &ShowThreadQueryThreadOnNewsPost) -> Node<Msg>
|
||||
],
|
||||
];
|
||||
div![
|
||||
C!["flex", "p-4"],
|
||||
C!["flex", "p-4", "bg-neutral-800"],
|
||||
div![favicon],
|
||||
div![
|
||||
C!["px-4", "mr-auto"],
|
||||
@ -1329,6 +1302,7 @@ fn render_news_post_header(post: &ShowThreadQueryThreadOnNewsPost) -> Node<Msg>
|
||||
]
|
||||
}
|
||||
fn reading_progress(ratio: f64) -> Node<Msg> {
|
||||
return div![];
|
||||
let percent = ratio * 100.;
|
||||
info!("percent {percent}");
|
||||
div![
|
||||
@ -1336,7 +1310,7 @@ fn reading_progress(ratio: f64) -> Node<Msg> {
|
||||
"fixed",
|
||||
"top-0",
|
||||
"left-0",
|
||||
"w-screen",
|
||||
"w-full",
|
||||
"h-1",
|
||||
"bg-gray-200",
|
||||
IF!(percent<1. => "hidden")
|
||||
|
||||
33
web/static/overrides.css
Normal file
33
web/static/overrides.css
Normal file
@ -0,0 +1,33 @@
|
||||
html {
|
||||
background-color: black;
|
||||
}
|
||||
|
||||
.news-post a {
|
||||
color: var(--color-link) !important;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.news-post br {
|
||||
display: block;
|
||||
margin-top: 1em;
|
||||
content: " ";
|
||||
}
|
||||
|
||||
.news-post h1,
|
||||
.news-post h2,
|
||||
.news-post h3,
|
||||
.news-post h4 {
|
||||
margin-top: 1em !important;
|
||||
margin-bottom: 1em !important;
|
||||
}
|
||||
|
||||
.news-post p {
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
|
||||
.news-post pre,
|
||||
.news-post code {
|
||||
font-family: monospace;
|
||||
background-color: #eee !important;
|
||||
padding: 0.5em !important;
|
||||
}
|
||||
42
web/static/vars.css
Normal file
42
web/static/vars.css
Normal file
@ -0,0 +1,42 @@
|
||||
:root {
|
||||
--active-brightness: 0.85;
|
||||
--border-radius: 5px;
|
||||
--box-shadow: 2px 2px 10px;
|
||||
--color-accent: #118bee15;
|
||||
--color-bg: #fff;
|
||||
--color-bg-secondary: #e9e9e9;
|
||||
--color-link: #118bee;
|
||||
--color-secondary: #920de9;
|
||||
--color-secondary-accent: #920de90b;
|
||||
--color-shadow: #f4f4f4;
|
||||
--color-table: #118bee;
|
||||
--color-text: #000;
|
||||
--color-text-secondary: #999;
|
||||
--color-scrollbar: #cacae8;
|
||||
--font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif;
|
||||
--hover-brightness: 1.2;
|
||||
--justify-important: center;
|
||||
--justify-normal: left;
|
||||
--line-height: 1.5;
|
||||
/*
|
||||
--width-card: 285px;
|
||||
--width-card-medium: 460px;
|
||||
--width-card-wide: 800px;
|
||||
*/
|
||||
--width-content: 1080px;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
:root[color-mode="user"] {
|
||||
--color-accent: #0097fc4f;
|
||||
--color-bg: #333;
|
||||
--color-bg-secondary: #555;
|
||||
--color-link: #0097fc;
|
||||
--color-secondary: #e20de9;
|
||||
--color-secondary-accent: #e20de94f;
|
||||
--color-shadow: #bbbbbb20;
|
||||
--color-table: #0097fc;
|
||||
--color-text: #f7f7f7;
|
||||
--color-text-secondary: #aaa;
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user