diff --git a/utils/mdhtml/lib.rs b/utils/mdhtml/lib.rs index 4eef71bd..4bc6a159 100644 --- a/utils/mdhtml/lib.rs +++ b/utils/mdhtml/lib.rs @@ -51,13 +51,12 @@ impl TokenSink for Sink { } }, "a" => { - let mut any_attr = !tag.attrs.is_empty(); + let any_attr = !tag.attrs.is_empty(); for attr in tag.attrs { match attr.name.local.as_ref() { "href" => self.buffer.push_str(&format!(" href=\"{}\"", attr.value.as_ref())), "title" => self.buffer.push_str(&format!(" title=\"{}\"", attr.value.as_ref())), "class" => if attr.value.as_ref() == "u-url mention" { - any_attr = false; self.buffer.push_str(" class=\"u-url mention\"") }, _ => {}, diff --git a/web/src/objects/item.rs b/web/src/objects/item.rs index 61e46992..02393842 100644 --- a/web/src/objects/item.rs +++ b/web/src/objects/item.rs @@ -6,10 +6,6 @@ use crate::prelude::*; use apb::{field::OptionalString, target::Addressed, ActivityMut, Base, Collection, CollectionMut, Object, ObjectMut}; -lazy_static::lazy_static! { - static ref REGEX: Regex = regex::Regex::new("@(\\w+)(@\\w+|)").expect("failed compiling @ regex"); -} - #[component] pub fn Object( object: crate::Object, @@ -39,23 +35,7 @@ pub fn Object( Some(view! {
}) }; - let mut content = mdhtml::safe_html(object.content().unwrap_or_default()); - - let mut results = vec![]; - for (matched, [id, username, _domain]) in REGEX.captures_iter(&content).map(|c| c.extract()) { - // TODO what the fuck mastodon........... why are you putting the fancy url in the A HREF???????? - let id = id.replace('@', "users/"); - // TODO ughh ugly on-the-fly html editing, can this be avoided? - let to_replace = format!( - "@{}", - Uri::web(U::Actor, &id), id, username - ); - results.push((matched.to_string(), to_replace)); - } - - for (from, to) in results { - content = content.replace(&from, &to); - } + let content = mdhtml::safe_html(object.content().unwrap_or_default()); let audience_badge = object.audience().id().str() .map(|x| view! { @@ -70,21 +50,45 @@ pub fn Object( }); let hashtag_badges = object.tag().filter_map(|x| { - if let Ok(apb::LinkType::Hashtag) = apb::Link::link_type(&x) { - let name = apb::Link::name(&x).unwrap_or_default().replace('#', ""); - let href = Uri::web(U::Hashtag, &name); - Some(view! { - - - # - - {name} - - - " " - }) - } else { - None + match apb::Link::link_type(&x) { + Ok(apb::LinkType::Hashtag) => { + let name = apb::Link::name(&x).unwrap_or_default().replace('#', ""); + let href = Uri::web(U::Hashtag, &name); + Some(view! { + + + # + + {name} + + + " " + }) + }, + Ok(apb::LinkType::Mention) => { + let uid = apb::Link::href(&x); + let mention = apb::Link::name(&x).unwrap_or_default().replacen('@', "", 1); + let (username, domain) = if let Some((username, server)) = mention.split_once('@') { + (username.to_string(), server.to_string()) + } else { + ( + mention.to_string(), + uid.replace("https://", "").replace("http://", "").split('/').next().unwrap_or_default().to_string(), + ) + }; + let href = Uri::web(U::Actor, uid); + Some(view! { + + + @ + + {username} + + + " " + }) + }, + _ => None, } }).collect_view();