From d48642132b95d667d0a3e437d21a5c3701d95b5f Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Wed, 18 May 2022 02:58:49 -0600 Subject: [PATCH] Add custom content warnings/spoiler text --- app/Http/Controllers/Api/ApiV1Controller.php | 9 ++++- app/Http/Controllers/ComposeController.php | 5 +++ .../ActivityPub/Verb/CreateNote.php | 2 +- app/Transformer/ActivityPub/Verb/Note.php | 2 +- .../assets/js/components/ComposeModal.vue | 39 ++++++++++++++----- .../presenter/PhotoAlbumPresenter.vue | 2 +- .../components/presenter/PhotoPresenter.vue | 2 +- .../components/presenter/VideoPresenter.vue | 2 +- resources/assets/sass/custom.scss | 15 +++++++ resources/assets/sass/spa.scss | 37 ++++++++++++++++++ 10 files changed, 99 insertions(+), 16 deletions(-) diff --git a/app/Http/Controllers/Api/ApiV1Controller.php b/app/Http/Controllers/Api/ApiV1Controller.php index b7929f34c..84dadfbb3 100644 --- a/app/Http/Controllers/Api/ApiV1Controller.php +++ b/app/Http/Controllers/Api/ApiV1Controller.php @@ -2289,6 +2289,7 @@ class ApiV1Controller extends Controller 'media_ids' => 'sometimes|array|max:' . config_cache('pixelfed.max_album_length'), 'sensitive' => 'nullable', 'visibility' => 'string|in:private,unlisted,public', + 'spoiler_text' => 'sometimes|string|max:140', ]); if(config('costar.enabled') == true) { @@ -2338,6 +2339,8 @@ class ApiV1Controller extends Controller $content = strip_tags($request->input('status')); $rendered = Autolink::create()->autolink($content); + $cw = $user->profile->cw == true ? true : $request->input('sensitive', false); + $spoilerText = $cw && $request->filled('spoiler_text') ? $request->input('spoiler_text') : null; if($in_reply_to_id) { $parent = Status::findOrFail($in_reply_to_id); @@ -2348,7 +2351,8 @@ class ApiV1Controller extends Controller $status->scope = $visibility; $status->visibility = $visibility; $status->profile_id = $user->profile_id; - $status->is_nsfw = $user->profile->cw == true ? true : $request->input('sensitive', false); + $status->is_nsfw = $cw; + $status->cw_summary = $spoilerText; $status->in_reply_to_id = $parent->id; $status->in_reply_to_profile_id = $parent->profile_id; $status->save(); @@ -2371,7 +2375,8 @@ class ApiV1Controller extends Controller $status->rendered = $rendered; $status->profile_id = $user->profile_id; $status->scope = 'draft'; - $status->is_nsfw = $user->profile->cw == true ? true : $request->input('sensitive', false); + $status->is_nsfw = $cw; + $status->cw_summary = $spoilerText; $status->save(); } diff --git a/app/Http/Controllers/ComposeController.php b/app/Http/Controllers/ComposeController.php index d420c79a1..b6b40bc6e 100644 --- a/app/Http/Controllers/ComposeController.php +++ b/app/Http/Controllers/ComposeController.php @@ -453,6 +453,7 @@ class ComposeController extends Controller 'tagged' => 'nullable', 'license' => 'nullable|integer|min:1|max:16', 'collections' => 'sometimes|array|min:1|max:5', + 'spoiler_text' => 'nullable|string|max:140', // 'optimize_media' => 'nullable' ]); @@ -540,6 +541,10 @@ class ComposeController extends Controller $status->comments_disabled = (bool) $request->input('comments_disabled'); } + if($request->filled('spoiler_text') && $cw) { + $status->cw_summary = $request->input('spoiler_text'); + } + $status->caption = strip_tags($request->caption); $status->rendered = Autolink::create()->autolink($status->caption); $status->scope = 'draft'; diff --git a/app/Transformer/ActivityPub/Verb/CreateNote.php b/app/Transformer/ActivityPub/Verb/CreateNote.php index 99cdcad34..1265cc258 100644 --- a/app/Transformer/ActivityPub/Verb/CreateNote.php +++ b/app/Transformer/ActivityPub/Verb/CreateNote.php @@ -93,7 +93,7 @@ class CreateNote extends Fractal\TransformerAbstract 'object' => [ 'id' => $status->url(), 'type' => 'Note', - 'summary' => null, + 'summary' => $status->is_nsfw ? $status->cw_summary : null, 'content' => $status->rendered ?? $status->caption, 'inReplyTo' => $status->in_reply_to_id ? $status->parent()->url() : null, 'published' => $status->created_at->toAtomString(), diff --git a/app/Transformer/ActivityPub/Verb/Note.php b/app/Transformer/ActivityPub/Verb/Note.php index 629a7c00b..939699890 100644 --- a/app/Transformer/ActivityPub/Verb/Note.php +++ b/app/Transformer/ActivityPub/Verb/Note.php @@ -87,7 +87,7 @@ class Note extends Fractal\TransformerAbstract ], 'id' => $status->url(), 'type' => 'Note', - 'summary' => null, + 'summary' => $status->is_nsfw ? $status->cw_summary : null, 'content' => $status->rendered ?? $status->caption, 'inReplyTo' => $status->in_reply_to_id ? $status->parent()->url() : null, 'published' => $status->created_at->toAtomString(), diff --git a/resources/assets/js/components/ComposeModal.vue b/resources/assets/js/components/ComposeModal.vue index d6157bb2c..9334d6694 100644 --- a/resources/assets/js/components/ComposeModal.vue +++ b/resources/assets/js/components/ComposeModal.vue @@ -432,15 +432,28 @@ -
-
-
Contains NSFW Media
-
-
-
- - +
+
+
+
Contains NSFW Media
+
+
+ + +
+
+
+ +
+ + +

{{ spoilerTextLength }}/140

@@ -1009,6 +1022,13 @@ export default { collectionsLoaded: false, collectionsPage: 1, collectionsCanLoadMore: false, + spoilerText: undefined, + } + }, + + computed: { + spoilerTextLength: function() { + return this.spoilerText ? this.spoilerText.length : 0; } }, @@ -1248,7 +1268,8 @@ export default { tagged: this.taggedUsernames, optimize_media: this.optimizeMedia, license: this.licenseId, - video: this.video + video: this.video, + spoiler_text: this.spoilerText, }; if(this.collectionsSelected.length) { diff --git a/resources/assets/js/components/presenter/PhotoAlbumPresenter.vue b/resources/assets/js/components/presenter/PhotoAlbumPresenter.vue index 033727f9f..c83f11e20 100644 --- a/resources/assets/js/components/presenter/PhotoAlbumPresenter.vue +++ b/resources/assets/js/components/presenter/PhotoAlbumPresenter.vue @@ -7,7 +7,7 @@

Sensitive Content

-

+

diff --git a/resources/assets/js/components/presenter/PhotoPresenter.vue b/resources/assets/js/components/presenter/PhotoPresenter.vue index 71159b163..eca896b0f 100644 --- a/resources/assets/js/components/presenter/PhotoPresenter.vue +++ b/resources/assets/js/components/presenter/PhotoPresenter.vue @@ -7,7 +7,7 @@

Sensitive Content

-

+

diff --git a/resources/assets/js/components/presenter/VideoPresenter.vue b/resources/assets/js/components/presenter/VideoPresenter.vue index ae5145918..4395c34ca 100644 --- a/resources/assets/js/components/presenter/VideoPresenter.vue +++ b/resources/assets/js/components/presenter/VideoPresenter.vue @@ -7,7 +7,7 @@

Sensitive Content

-

+

diff --git a/resources/assets/sass/custom.scss b/resources/assets/sass/custom.scss index 4d631b991..7d927f233 100644 --- a/resources/assets/sass/custom.scss +++ b/resources/assets/sass/custom.scss @@ -652,3 +652,18 @@ details summary::-webkit-details-marker { font-weight: bold; } } + +.content-label { + &-wrapper { + div:not(.content-label) { + height: 100%; + } + } + + &-text { + width: 80%; + @media (min-width: 768px) { + width: 50%; + } + } +} diff --git a/resources/assets/sass/spa.scss b/resources/assets/sass/spa.scss index 43a9a949c..3fea3e7e2 100644 --- a/resources/assets/sass/spa.scss +++ b/resources/assets/sass/spa.scss @@ -291,3 +291,40 @@ span.twitter-typeahead .tt-suggestion:focus { color: var(--body-color); } } + +.ui-menu { + .btn-group { + .btn:first-child { + border-top-left-radius: 50rem; + border-bottom-left-radius: 50rem; + } + + .btn:last-child { + border-top-right-radius: 50rem; + border-bottom-right-radius: 50rem; + } + + .btn-primary { + font-weight: bold; + } + } + + .b-custom-control-lg { + padding-bottom: 8px; + } +} + +.content-label { + &-wrapper { + div:not(.content-label) { + height: 100%; + } + } + + &-text { + width: 80%; + @media (min-width: 768px) { + width: 50%; + } + } +}