Hide cw pictures behind a summary/details (#483)
* Hide cw pictures behind a summary/details * refactor md_to_html a bit and add cw support * use random id for cw checkbox
This commit is contained in:
@@ -11,6 +11,7 @@ use std::collections::HashSet;
|
||||
|
||||
use comment_seers::{CommentSeers, NewCommentSeers};
|
||||
use instance::Instance;
|
||||
use medias::Media;
|
||||
use mentions::Mention;
|
||||
use notifications::*;
|
||||
use plume_common::activity_pub::{
|
||||
@@ -102,14 +103,16 @@ impl Comment {
|
||||
.unwrap_or(false)
|
||||
}
|
||||
|
||||
pub fn to_activity(&self, conn: &Connection) -> Result<Note> {
|
||||
pub fn to_activity<'b>(&self, conn: &'b Connection) -> Result<Note> {
|
||||
let author = User::get(conn, self.author_id)?;
|
||||
|
||||
let (html, mentions, _hashtags) = utils::md_to_html(
|
||||
self.content.get().as_ref(),
|
||||
&Instance::get_local(conn)?.public_domain,
|
||||
true,
|
||||
Some(Media::get_media_processor(conn, vec![&author])),
|
||||
);
|
||||
|
||||
let author = User::get(conn, self.author_id)?;
|
||||
let mut note = Note::default();
|
||||
let to = vec![Id::new(PUBLIC_VISIBILTY.to_string())];
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ use diesel::{self, ExpressionMethods, QueryDsl, RunQueryDsl};
|
||||
use std::iter::Iterator;
|
||||
|
||||
use ap_url;
|
||||
use medias::Media;
|
||||
use plume_common::utils::md_to_html;
|
||||
use safe_string::SafeString;
|
||||
use schema::{instances, users};
|
||||
@@ -128,8 +129,18 @@ impl Instance {
|
||||
short_description: SafeString,
|
||||
long_description: SafeString,
|
||||
) -> Result<()> {
|
||||
let (sd, _, _) = md_to_html(short_description.as_ref(), &self.public_domain, true);
|
||||
let (ld, _, _) = md_to_html(long_description.as_ref(), &self.public_domain, false);
|
||||
let (sd, _, _) = md_to_html(
|
||||
short_description.as_ref(),
|
||||
&self.public_domain,
|
||||
true,
|
||||
Some(Media::get_media_processor(conn, vec![])),
|
||||
);
|
||||
let (ld, _, _) = md_to_html(
|
||||
long_description.as_ref(),
|
||||
&self.public_domain,
|
||||
false,
|
||||
Some(Media::get_media_processor(conn, vec![])),
|
||||
);
|
||||
diesel::update(self)
|
||||
.set((
|
||||
instances::name.eq(name),
|
||||
|
||||
@@ -5,7 +5,7 @@ use guid_create::GUID;
|
||||
use reqwest;
|
||||
use std::{fs, path::Path};
|
||||
|
||||
use plume_common::activity_pub::Id;
|
||||
use plume_common::{activity_pub::Id, utils::MediaProcessor};
|
||||
|
||||
use instance::Instance;
|
||||
use safe_string::SafeString;
|
||||
@@ -124,10 +124,9 @@ impl Media {
|
||||
}
|
||||
|
||||
pub fn markdown(&self, conn: &Connection) -> Result<SafeString> {
|
||||
let url = self.url(conn)?;
|
||||
Ok(match self.category() {
|
||||
MediaCategory::Image => {
|
||||
SafeString::new(&format!("", escape(&self.alt_text), url))
|
||||
SafeString::new(&format!("", escape(&self.alt_text), self.id))
|
||||
}
|
||||
MediaCategory::Audio | MediaCategory::Video => self.html(conn)?,
|
||||
MediaCategory::Unknown => SafeString::new(""),
|
||||
@@ -225,6 +224,19 @@ impl Media {
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
pub fn get_media_processor<'a>(conn: &'a Connection, user: Vec<&User>) -> MediaProcessor<'a> {
|
||||
let uid = user.iter().map(|u| u.id).collect::<Vec<_>>();
|
||||
Box::new(move |id| {
|
||||
let media = Media::get(conn, id).ok()?;
|
||||
// if owner is user or check is disabled
|
||||
if uid.contains(&media.owner_id) || uid.is_empty() {
|
||||
Some((media.url(conn).ok()?, media.content_warning))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
||||
@@ -207,17 +207,19 @@ impl<'a> Provider<(&'a Connection, &'a Worker, &'a Searcher, Option<i32>)> for P
|
||||
let domain = &Instance::get_local(&conn)
|
||||
.map_err(|_| ApiError::NotFound("posts::update: Error getting local instance".into()))?
|
||||
.public_domain;
|
||||
let (content, mentions, hashtags) = md_to_html(
|
||||
query.source.clone().unwrap_or_default().clone().as_ref(),
|
||||
domain,
|
||||
false,
|
||||
);
|
||||
|
||||
let author = User::get(
|
||||
conn,
|
||||
user_id.expect("<Post as Provider>::create: no user_id error"),
|
||||
)
|
||||
.map_err(|_| ApiError::NotFound("Author not found".into()))?;
|
||||
|
||||
let (content, mentions, hashtags) = md_to_html(
|
||||
query.source.clone().unwrap_or_default().clone().as_ref(),
|
||||
domain,
|
||||
false,
|
||||
Some(Media::get_media_processor(conn, vec![&author])),
|
||||
);
|
||||
|
||||
let blog = match query.blog_id {
|
||||
Some(x) => x,
|
||||
None => {
|
||||
@@ -757,7 +759,7 @@ impl Post {
|
||||
post.license = license;
|
||||
}
|
||||
|
||||
let mut txt_hashtags = md_to_html(&post.source, "", false)
|
||||
let mut txt_hashtags = md_to_html(&post.source, "", false, None)
|
||||
.2
|
||||
.into_iter()
|
||||
.map(|s| s.to_camel_case())
|
||||
@@ -995,7 +997,7 @@ impl<'a> FromActivity<LicensedArticle, (&'a Connection, &'a Searcher)> for Post
|
||||
}
|
||||
|
||||
// save mentions and tags
|
||||
let mut hashtags = md_to_html(&post.source, "", false)
|
||||
let mut hashtags = md_to_html(&post.source, "", false, None)
|
||||
.2
|
||||
.into_iter()
|
||||
.map(|s| s.to_camel_case())
|
||||
|
||||
@@ -19,7 +19,7 @@ lazy_static! {
|
||||
static ref CLEAN: Builder<'static> = {
|
||||
let mut b = Builder::new();
|
||||
b.add_generic_attributes(iter::once("id"))
|
||||
.add_tags(&["iframe", "video", "audio"])
|
||||
.add_tags(&["iframe", "video", "audio", "label", "input"])
|
||||
.id_prefix(Some("postcontent-"))
|
||||
.url_relative(UrlRelative::Custom(Box::new(url_add_prefix)))
|
||||
.add_tag_attributes(
|
||||
@@ -27,7 +27,23 @@ lazy_static! {
|
||||
["width", "height", "src", "frameborder"].iter().cloned(),
|
||||
)
|
||||
.add_tag_attributes("video", ["src", "title", "controls"].iter())
|
||||
.add_tag_attributes("audio", ["src", "title", "controls"].iter());
|
||||
.add_tag_attributes("audio", ["src", "title", "controls"].iter())
|
||||
.add_tag_attributes("label", ["for"].iter())
|
||||
.add_tag_attributes("input", ["type", "checked"].iter())
|
||||
.add_allowed_classes("input", ["cw-checkbox"].iter())
|
||||
.add_allowed_classes("span", ["cw-container", "cw-text"].iter())
|
||||
.attribute_filter(|elem, att, val| match (elem, att) {
|
||||
("input", "type") => Some("checkbox".into()),
|
||||
("input", "checked") => Some("checked".into()),
|
||||
("label", "for") => {
|
||||
if val.starts_with("postcontent-cw-") {
|
||||
Some(val.into())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
_ => Some(val.into()),
|
||||
});
|
||||
b
|
||||
};
|
||||
}
|
||||
|
||||
@@ -209,7 +209,13 @@ impl User {
|
||||
.set((
|
||||
users::display_name.eq(name),
|
||||
users::email.eq(email),
|
||||
users::summary_html.eq(utils::md_to_html(&summary, "", false).0),
|
||||
users::summary_html.eq(utils::md_to_html(
|
||||
&summary,
|
||||
"",
|
||||
false,
|
||||
Some(Media::get_media_processor(conn, vec![self])),
|
||||
)
|
||||
.0),
|
||||
users::summary.eq(summary),
|
||||
))
|
||||
.execute(conn)?;
|
||||
@@ -868,7 +874,7 @@ impl NewUser {
|
||||
display_name,
|
||||
is_admin,
|
||||
summary: summary.to_owned(),
|
||||
summary_html: SafeString::new(&utils::md_to_html(&summary, "", false).0),
|
||||
summary_html: SafeString::new(&utils::md_to_html(&summary, "", false, None).0),
|
||||
email: Some(email),
|
||||
hashed_password: Some(password),
|
||||
instance_id: Instance::get_local(conn)?.id,
|
||||
|
||||
Reference in New Issue
Block a user