diff --git a/profiles/src/lib.rs b/profiles/src/lib.rs index 7568998..4648af9 100644 --- a/profiles/src/lib.rs +++ b/profiles/src/lib.rs @@ -1,8 +1,9 @@ use activitystreams::base::AnyBase; use actix_rt::Arbiter; use actix_web::{client::Client, dev::Payload, HttpRequest}; +use hyaenidae_content::NodeView; use sled::Db; -use std::{fmt, sync::Arc}; +use std::{borrow::Cow, fmt, sync::Arc}; use url::Url; use uuid::Uuid; @@ -100,6 +101,11 @@ pub trait Outbound { } } +pub trait UrlFor { + fn profile(&self, profile: &store::Profile) -> String; + fn icon(&self, file: &store::File) -> String; +} + trait Required { fn req(self, msg: &str) -> Result; } @@ -122,6 +128,7 @@ pub struct State { pub apub: apub::Store, pub pictrs: pictrs::State, pub spawner: Arc, + pub url_for: Arc, pub arbiter: Arbiter, _db: Db, } @@ -132,6 +139,7 @@ impl State { image_info: impl ImageInfo + Send + Sync + 'static, apub_info: impl ApubIds + Send + Sync + 'static, spawner: impl Spawner + Send + Sync + 'static, + url_for: impl UrlFor + Send + Sync + 'static, arbiter: Arbiter, db: Db, ) -> Result, sled::Error> { @@ -140,11 +148,86 @@ impl State { apub: apub::Store::build(apub_info, &db)?, pictrs: pictrs::State::new(pictrs_upstream, image_info), spawner: Arc::new(spawner), + url_for: Arc::new(url_for), arbiter, _db: db, })) } + fn map_nodeview<'a>(&self, view: NodeView<'a>) -> NodeView<'a> { + match view { + NodeView::IconText { handle, domain, .. } => { + let id_res = self.store.profiles.by_handle(&handle, &domain); + if let Ok(Some(id)) = &id_res { + if let Ok(Some(profile)) = self.store.profiles.by_id(*id) { + if let Some(file_id) = profile.icon() { + if let Ok(Some(file)) = self.store.files.by_id(file_id) { + return NodeView::IconText { + handle, + domain, + href: Some(self.url_for.profile(&profile)), + img: Some(self.url_for.icon(&file)), + }; + } + } + + return NodeView::Handle { + handle, + domain, + href: Some(self.url_for.profile(&profile)), + }; + } + } + + NodeView::Text { + text: Cow::Owned(format!("@{}@{}", handle, domain)), + } + } + NodeView::Icon { handle, domain, .. } => { + if let Ok(Some(id)) = self.store.profiles.by_handle(&handle, &domain) { + if let Ok(Some(profile)) = self.store.profiles.by_id(id) { + if let Some(file_id) = profile.icon() { + if let Ok(Some(file)) = self.store.files.by_id(file_id) { + return NodeView::Icon { + handle, + domain, + href: Some(self.url_for.profile(&profile)), + img: Some(self.url_for.icon(&file)), + }; + } + } + + return NodeView::Handle { + handle, + domain, + href: Some(self.url_for.profile(&profile)), + }; + } + } + + NodeView::Text { + text: Cow::Owned(format!("@{}@{}", handle, domain)), + } + } + NodeView::Handle { handle, domain, .. } => { + if let Ok(Some(id)) = self.store.profiles.by_handle(&handle, &domain) { + if let Ok(Some(profile)) = self.store.profiles.by_id(id) { + return NodeView::Handle { + handle, + domain, + href: Some(self.url_for.profile(&profile)), + }; + } + } + + NodeView::Text { + text: Cow::Owned(format!("@{}@{}", handle, domain)), + } + } + rest => rest, + } + } + pub async fn create_server_actor(self: &Arc, domain: String) -> Result<(), Error> { let ctx = self.clone(); diff --git a/profiles/src/store/comment.rs b/profiles/src/store/comment.rs index 8e4c543..df67015 100644 --- a/profiles/src/store/comment.rs +++ b/profiles/src/store/comment.rs @@ -152,7 +152,7 @@ impl<'a> CommentChanges<'a> { pub(crate) fn body_source(&mut self, body_source: &str) -> &mut Self { self.body_source = Some(body_source.to_owned()); - self.body(&bbcode(body_source, |v| v)) + self.body(&bbcode(body_source, |v| self.state.map_nodeview(v))) } pub(crate) fn published(&mut self, published: DateTime) -> &mut Self { diff --git a/profiles/src/store/profile.rs b/profiles/src/store/profile.rs index 8f32f5f..92b4732 100644 --- a/profiles/src/store/profile.rs +++ b/profiles/src/store/profile.rs @@ -142,7 +142,7 @@ impl<'a> ProfileChanges<'a> { pub(crate) fn description_source(&mut self, description_source: &str) -> &mut Self { self.description_source = Some(description_source.to_owned()); - self.description(&bbcode(description_source, |v| v)) + self.description(&bbcode(description_source, |v| self.state.map_nodeview(v))) } pub(crate) fn login_required(&mut self, required: bool) -> &mut Self { @@ -663,7 +663,11 @@ fn id_profile_key(id: Uuid) -> String { // Used to map handle -> id fn handle_id_key(handle: &str, domain: &str) -> String { - format!("/handle/{}:{}/profile", handle, domain) + format!( + "/handle/{}:{}/profile", + handle.to_lowercase(), + domain.to_lowercase() + ) } fn handle_id_prefix(handle: &str) -> String { diff --git a/profiles/src/store/server.rs b/profiles/src/store/server.rs index 66e0eae..3a62118 100644 --- a/profiles/src/store/server.rs +++ b/profiles/src/store/server.rs @@ -130,7 +130,7 @@ impl<'a> ServerChanges<'a> { pub(crate) fn description_source(&mut self, description_source: &str) -> &mut Self { self.description_source = Some(description_source.to_owned()); - self.description(&bbcode(description_source, |v| v)) + self.description(&bbcode(description_source, |v| self.state.map_nodeview(v))) } pub(crate) fn published(&mut self, published: DateTime) -> &mut Self { diff --git a/profiles/src/store/submission.rs b/profiles/src/store/submission.rs index 3c90a1b..6ae0018 100644 --- a/profiles/src/store/submission.rs +++ b/profiles/src/store/submission.rs @@ -212,7 +212,7 @@ impl<'a> SubmissionChanges<'a> { pub(crate) fn description_source(&mut self, description_source: &str) -> &mut Self { self.description_source = Some(description_source.to_owned()); - self.description(&bbcode(description_source, |v| v)) + self.description(&bbcode(description_source, |v| self.state.map_nodeview(v))) } pub(crate) fn visibility(&mut self, visibility: Visibility) -> &mut Self {