Add support for content warnings

This commit is contained in:
silverpill 2023-04-15 23:43:19 +00:00 committed by Rafael Caricio
parent 1302611731
commit f41b205084
Signed by: rafaelcaricio
GPG key ID: 3C86DBCE8E93C947
12 changed files with 44 additions and 5 deletions

View file

@ -6,6 +6,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
## [Unreleased] ## [Unreleased]
### Added
- Added support for content warnings.
### Changed ### Changed
- Ignore errors when importing activities from outbox. - Ignore errors when importing activities from outbox.

View file

@ -959,6 +959,10 @@ paths:
visibility: visibility:
description: Visibility of the post. description: Visibility of the post.
$ref: '#/components/schemas/Visibility' $ref: '#/components/schemas/Visibility'
sensitiive:
description: Mark post and attached media as sensitive?
type: boolean
default: false
mentions: mentions:
description: Array of profile IDs to be mentioned description: Array of profile IDs to be mentioned
type: array type: array
@ -1907,6 +1911,10 @@ components:
visibility: visibility:
description: Visibility of this post. description: Visibility of this post.
$ref: '#/components/schemas/Visibility' $ref: '#/components/schemas/Visibility'
sensitiive:
description: Is this post marked as sensitive content?
type: boolean
example: false
spoiler_text: spoiler_text:
description: Subject or summary line, below which post content is collapsed until expanded. description: Subject or summary line, below which post content is collapsed until expanded.
type: string type: string

View file

@ -0,0 +1,2 @@
ALTER TABLE post ADD COLUMN is_sensitive BOOLEAN NOT NULL DEFAULT FALSE;
ALTER TABLE post ALTER COLUMN is_sensitive DROP DEFAULT;

View file

@ -116,7 +116,8 @@ CREATE TABLE post (
content TEXT NOT NULL, content TEXT NOT NULL,
in_reply_to_id UUID REFERENCES post (id) ON DELETE CASCADE, in_reply_to_id UUID REFERENCES post (id) ON DELETE CASCADE,
repost_of_id UUID REFERENCES post (id) ON DELETE CASCADE, repost_of_id UUID REFERENCES post (id) ON DELETE CASCADE,
visilibity SMALLINT NOT NULL, visibility SMALLINT NOT NULL,
is_sensitive BOOLEAN NOT NULL,
reply_count INTEGER NOT NULL CHECK (reply_count >= 0) DEFAULT 0, reply_count INTEGER NOT NULL CHECK (reply_count >= 0) DEFAULT 0,
reaction_count INTEGER NOT NULL CHECK (reaction_count >= 0) DEFAULT 0, reaction_count INTEGER NOT NULL CHECK (reaction_count >= 0) DEFAULT 0,
repost_count INTEGER NOT NULL CHECK (repost_count >= 0) DEFAULT 0, repost_count INTEGER NOT NULL CHECK (repost_count >= 0) DEFAULT 0,

View file

@ -183,10 +183,11 @@ pub async fn create_post(
in_reply_to_id, in_reply_to_id,
repost_of_id, repost_of_id,
visibility, visibility,
is_sensitive,
object_id, object_id,
created_at created_at
) )
SELECT $1, $2, $3, $4, $5, $6, $7, $8 SELECT $1, $2, $3, $4, $5, $6, $7, $8, $9
WHERE WHERE
NOT EXISTS ( NOT EXISTS (
SELECT 1 FROM post SELECT 1 FROM post
@ -212,6 +213,7 @@ pub async fn create_post(
&post_data.in_reply_to_id, &post_data.in_reply_to_id,
&post_data.repost_of_id, &post_data.repost_of_id,
&post_data.visibility, &post_data.visibility,
&post_data.is_sensitive,
&post_data.object_id, &post_data.object_id,
&post_data.created_at, &post_data.created_at,
], ],
@ -324,14 +326,16 @@ pub async fn update_post(
UPDATE post UPDATE post
SET SET
content = $1, content = $1,
updated_at = $2 is_sensitive = $2,
WHERE id = $3 updated_at = $3
WHERE id = $4
AND repost_of_id IS NULL AND repost_of_id IS NULL
AND ipfs_cid IS NULL AND ipfs_cid IS NULL
RETURNING post RETURNING post
", ",
&[ &[
&post_data.content, &post_data.content,
&post_data.is_sensitive,
&post_data.updated_at, &post_data.updated_at,
&post_id, &post_id,
], ],

View file

@ -62,6 +62,7 @@ pub struct DbPost {
pub in_reply_to_id: Option<Uuid>, pub in_reply_to_id: Option<Uuid>,
pub repost_of_id: Option<Uuid>, pub repost_of_id: Option<Uuid>,
pub visibility: Visibility, pub visibility: Visibility,
pub is_sensitive: bool,
pub reply_count: i32, pub reply_count: i32,
pub reaction_count: i32, pub reaction_count: i32,
pub repost_count: i32, pub repost_count: i32,
@ -88,6 +89,7 @@ pub struct Post {
pub in_reply_to_id: Option<Uuid>, pub in_reply_to_id: Option<Uuid>,
pub repost_of_id: Option<Uuid>, pub repost_of_id: Option<Uuid>,
pub visibility: Visibility, pub visibility: Visibility,
pub is_sensitive: bool,
pub reply_count: i32, pub reply_count: i32,
pub reaction_count: i32, pub reaction_count: i32,
pub repost_count: i32, pub repost_count: i32,
@ -130,6 +132,7 @@ impl Post {
}; };
if db_post.repost_of_id.is_some() && ( if db_post.repost_of_id.is_some() && (
db_post.content.len() != 0 || db_post.content.len() != 0 ||
db_post.is_sensitive ||
db_post.in_reply_to_id.is_some() || db_post.in_reply_to_id.is_some() ||
db_post.ipfs_cid.is_some() || db_post.ipfs_cid.is_some() ||
db_post.token_id.is_some() || db_post.token_id.is_some() ||
@ -149,6 +152,7 @@ impl Post {
in_reply_to_id: db_post.in_reply_to_id, in_reply_to_id: db_post.in_reply_to_id,
repost_of_id: db_post.repost_of_id, repost_of_id: db_post.repost_of_id,
visibility: db_post.visibility, visibility: db_post.visibility,
is_sensitive: db_post.is_sensitive,
reply_count: db_post.reply_count, reply_count: db_post.reply_count,
reaction_count: db_post.reaction_count, reaction_count: db_post.reaction_count,
repost_count: db_post.repost_count, repost_count: db_post.repost_count,
@ -190,6 +194,7 @@ impl Default for Post {
in_reply_to_id: None, in_reply_to_id: None,
repost_of_id: None, repost_of_id: None,
visibility: Visibility::Public, visibility: Visibility::Public,
is_sensitive: false,
reply_count: 0, reply_count: 0,
reaction_count: 0, reaction_count: 0,
repost_count: 0, repost_count: 0,
@ -243,6 +248,7 @@ pub struct PostCreateData {
pub in_reply_to_id: Option<Uuid>, pub in_reply_to_id: Option<Uuid>,
pub repost_of_id: Option<Uuid>, pub repost_of_id: Option<Uuid>,
pub visibility: Visibility, pub visibility: Visibility,
pub is_sensitive: bool,
pub attachments: Vec<Uuid>, pub attachments: Vec<Uuid>,
pub mentions: Vec<Uuid>, pub mentions: Vec<Uuid>,
pub tags: Vec<String>, pub tags: Vec<String>,
@ -269,6 +275,7 @@ impl PostCreateData {
#[cfg_attr(test, derive(Default))] #[cfg_attr(test, derive(Default))]
pub struct PostUpdateData { pub struct PostUpdateData {
pub content: String, pub content: String,
pub is_sensitive: bool,
pub attachments: Vec<Uuid>, pub attachments: Vec<Uuid>,
pub mentions: Vec<Uuid>, pub mentions: Vec<Uuid>,
pub tags: Vec<String>, pub tags: Vec<String>,

View file

@ -70,6 +70,7 @@ pub struct Note {
in_reply_to: Option<String>, in_reply_to: Option<String>,
published: DateTime<Utc>, published: DateTime<Utc>,
sensitive: bool,
#[serde(skip_serializing_if = "Vec::is_empty")] #[serde(skip_serializing_if = "Vec::is_empty")]
tag: Vec<Tag>, tag: Vec<Tag>,
@ -205,10 +206,11 @@ pub fn build_note(
id: object_id, id: object_id,
object_type: NOTE.to_string(), object_type: NOTE.to_string(),
attachment: attachments, attachment: attachments,
published: post.created_at,
attributed_to: actor_id, attributed_to: actor_id,
in_reply_to: in_reply_to_object_id, in_reply_to: in_reply_to_object_id,
content: post.content.clone(), content: post.content.clone(),
published: post.created_at,
sensitive: post.is_sensitive,
tag: tags, tag: tags,
to: primary_audience, to: primary_audience,
cc: secondary_audience, cc: secondary_audience,

View file

@ -639,12 +639,14 @@ pub async fn handle_note(
author.username, author.username,
); );
}; };
let is_sensitive = object.sensitive.unwrap_or(false);
let created_at = object.published.unwrap_or(Utc::now()); let created_at = object.published.unwrap_or(Utc::now());
let post_data = PostCreateData { let post_data = PostCreateData {
content: content, content: content,
in_reply_to_id, in_reply_to_id,
repost_of_id: None, repost_of_id: None,
visibility, visibility,
is_sensitive,
attachments: attachments, attachments: attachments,
mentions: mentions, mentions: mentions,
tags: hashtags, tags: hashtags,

View file

@ -69,6 +69,7 @@ async fn handle_update_note(
let object_url = get_object_url(&object)?; let object_url = get_object_url(&object)?;
content += &create_content_link(object_url); content += &create_content_link(object_url);
}; };
let is_sensitive = object.sensitive.unwrap_or(false);
let storage = MediaStorage::from(config); let storage = MediaStorage::from(config);
let (attachments, unprocessed) = get_object_attachments( let (attachments, unprocessed) = get_object_attachments(
db_client, db_client,
@ -93,6 +94,7 @@ async fn handle_update_note(
let updated_at = object.updated.unwrap_or(Utc::now()); let updated_at = object.updated.unwrap_or(Utc::now());
let post_data = PostUpdateData { let post_data = PostUpdateData {
content, content,
is_sensitive,
attachments, attachments,
mentions, mentions,
tags: hashtags, tags: hashtags,

View file

@ -122,6 +122,7 @@ pub struct Object {
pub in_reply_to: Option<String>, pub in_reply_to: Option<String>,
pub content: Option<String>, pub content: Option<String>,
pub quote_url: Option<String>, pub quote_url: Option<String>,
pub sensitive: Option<bool>,
#[serde( #[serde(
default, default,

View file

@ -69,6 +69,7 @@ pub struct Status {
pub in_reply_to_id: Option<Uuid>, pub in_reply_to_id: Option<Uuid>,
pub reblog: Option<Box<Status>>, pub reblog: Option<Box<Status>>,
pub visibility: String, pub visibility: String,
pub sensitive: bool,
pub spoiler_text: Option<String>, pub spoiler_text: Option<String>,
pub replies_count: i32, pub replies_count: i32,
pub favourites_count: i32, pub favourites_count: i32,
@ -138,6 +139,7 @@ impl Status {
in_reply_to_id: post.in_reply_to_id, in_reply_to_id: post.in_reply_to_id,
reblog: reblog, reblog: reblog,
visibility: visibility.to_string(), visibility: visibility.to_string(),
sensitive: post.is_sensitive,
spoiler_text: None, spoiler_text: None,
replies_count: post.reply_count, replies_count: post.reply_count,
favourites_count: post.reaction_count, favourites_count: post.reaction_count,
@ -169,6 +171,9 @@ pub struct StatusData {
pub in_reply_to_id: Option<Uuid>, pub in_reply_to_id: Option<Uuid>,
pub visibility: Option<String>, pub visibility: Option<String>,
#[serde(default)]
pub sensitive: bool,
// Not supported by Mastodon // Not supported by Mastodon
pub mentions: Option<Vec<Uuid>>, pub mentions: Option<Vec<Uuid>>,

View file

@ -189,6 +189,7 @@ async fn create_status(
in_reply_to_id: status_data.in_reply_to_id, in_reply_to_id: status_data.in_reply_to_id,
repost_of_id: None, repost_of_id: None,
visibility: visibility, visibility: visibility,
is_sensitive: status_data.sensitive,
attachments: attachments, attachments: attachments,
mentions: mentions, mentions: mentions,
tags: hashtags, tags: hashtags,