Posts have text content

main
Ashelyn Dawn 1 year ago
parent 76fb8e6c08
commit c30aa74f51

27
Cargo.lock generated

@ -12,6 +12,7 @@ dependencies = [
"flate2",
"fs_extra",
"futures",
"regex",
"serde",
"serde_json",
"tar",
@ -25,6 +26,15 @@ version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
[[package]]
name = "aho-corasick"
version = "0.7.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cc936419f96fa211c1b9166887b38e5e40b19958e5b895be7c1f93adec7071ac"
dependencies = [
"memchr",
]
[[package]]
name = "android_system_properties"
version = "0.1.5"
@ -863,6 +873,23 @@ dependencies = [
"bitflags",
]
[[package]]
name = "regex"
version = "1.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "48aaa5748ba571fb95cd2c85c09f629215d3a6ece942baa100950af03a34f733"
dependencies = [
"aho-corasick",
"memchr",
"regex-syntax",
]
[[package]]
name = "regex-syntax"
version = "0.6.28"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "456c603be3e8d448b072f410900c09faf164fbce2d480456f50eea6e25f9c848"
[[package]]
name = "rustix"
version = "0.36.8"

@ -17,3 +17,4 @@ yew = { version = "0.20.0", features = ["ssr", "csr"] }
console_error_panic_hook = { version ="0.1" }
wasm-bindgen = {version = "0.2" }
fs_extra = "1.3.0"
regex = "1.7.1"

@ -97,3 +97,21 @@ h1.name {
.bio {
font-size: 14px;
}
.posts-info {
border-top: solid 1px gray;
border-bottom: solid 1px gray;
margin: var(--body-padding) calc(var(--body-padding) * -1);
margin-bottom: 0;
padding: var(--body-padding);
}
.posts {
margin: 0 calc(var(--body-padding) * -1);
}
.post {
border-bottom: solid 1px gray;
padding: var(--body-padding);
}

@ -71,28 +71,28 @@ pub enum Item {
#[derive(Deserialize, Debug, PartialEq, Clone)]
pub struct CommonFields {
id: String,
actor: String,
published: String,
to: Vec<String>,
cc: Vec<String>,
pub id: String,
pub actor: String,
pub published: String,
pub to: Vec<String>,
pub cc: Vec<String>,
}
#[derive(Deserialize, Debug, PartialEq, Clone)]
#[serde(rename_all = "camelCase")]
pub struct Post {
summary: Option<String>,
in_reply_to: Option<String>,
url: String,
sensitive: bool,
content: String,
pub summary: Option<String>,
pub in_reply_to: Option<String>,
pub url: String,
pub sensitive: bool,
pub content: String,
#[serde(rename = "attachment")]
attachments: Option<Vec<Attachment>>,
pub attachments: Option<Vec<Attachment>>,
tag: Option<Vec<Tag>>,
replies: Option<Collection>,
quote_uri: Option<String>,
pub tag: Option<Vec<Tag>>,
pub replies: Option<Collection>,
pub quote_uri: Option<String>,
}
#[derive(Deserialize, Debug, PartialEq, Clone)]

@ -1,5 +1,8 @@
use std::str::FromStr;
use chrono::DateTime;
use futures::executor;
use regex::Regex;
use yew::{function_component, html, AttrValue, Html, Renderer, ServerRenderer};
#[cfg(debug_assertions)]
@ -8,7 +11,7 @@ use console_error_panic_hook::set_once as set_panic_hook;
use yew::prelude::*;
use crate::{
data::{Attachment, Outbox, Person},
data::{Attachment, CommonFields, Item, Outbox, Person, Post as DataPost},
error::Ærror,
};
@ -19,6 +22,13 @@ struct Props {
pub archive_time: DateTime<chrono::Utc>,
}
#[derive(yew::Properties, PartialEq)]
struct PostProps {
pub meta: CommonFields,
pub post: DataPost,
pub author: Person,
}
#[cfg(not(debug_assertions))]
pub fn render_ssr(
outbox: Outbox,
@ -73,6 +83,7 @@ fn Layout(props: &Props) -> Html {
html! {
<>
<ProfileHeader outbox={props.outbox.clone()} author={props.author.clone()} archive_time={props.archive_time}/>
<Posts outbox={props.outbox.clone()} author={props.author.clone()} archive_time={props.archive_time}/>
</>
}
}
@ -133,7 +144,67 @@ fn ProfileHeader(props: &Props) -> Html {
#[function_component]
fn Posts(props: &Props) -> Html {
let public = &String::from_str("https://www.w3.org/ns/activitystreams#Public").unwrap();
let author_str = props.author.clone().id;
let mut ordered_items = props.outbox.clone().ordered_items;
ordered_items.reverse();
let posts: Vec<(CommonFields, DataPost)> = ordered_items
.into_iter()
.filter_map(|item| match item {
Item::Post { meta, object } => {
if meta.to.contains(public)
&& object.in_reply_to.is_none()
&& meta.actor == author_str
{
Some((meta, object))
} else {
None
}
}
_ => None,
})
.collect();
html! {
<p>{"Posts"}</p>
<>
<div class="posts-info">
{posts.len()}
{" posts"}
</div>
<div class="posts">
{posts.into_iter().map(|(meta, post)| {
html! {
<Post post={post} meta={meta} author={props.author.clone()}/>
}
}).collect::<Html>()}
</div>
</>
}
}
#[function_component]
fn Post(props: &PostProps) -> Html {
let post = props.post.clone();
let meta = props.meta.clone();
let post_time_utc = DateTime::parse_from_rfc3339(meta.published.as_str()).unwrap();
let post_time = DateTime::<chrono::offset::Local>::from(post_time_utc);
let mut content = String::from_str(&post.content).unwrap();
if post.quote_uri.is_some() {
let regex = Regex::new("<span class=\"quote-inline\">.*</span>").unwrap();
content = String::from_str(&regex.replace(&content.as_str(), "")).unwrap();
}
html! {
<div class="post">
<div class="post-contents">
{Html::from_html_unchecked(AttrValue::from(content))}
</div>
<span class="post-date">{post_time.format("%b %e, %Y, %H:%M")}</span>
</div>
}
}

Loading…
Cancel
Save