1
0
Эх сурвалжийг харах

Add custom content warnings/spoiler text

Daniel Supernault 3 жил өмнө
parent
commit
d48642132b

+ 7 - 2
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();
 			}
 

+ 5 - 0
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';

+ 1 - 1
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(),

+ 1 - 1
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(),

+ 30 - 9
resources/assets/js/components/ComposeModal.vue

@@ -432,16 +432,29 @@
 								</div>
 							</div>
 						</div>
-						<div class="border-bottom d-flex justify-content-between px-4 mb-0 py-2 ">
-							<div>
-								<div class="text-dark ">Contains NSFW Media</div>
-							</div>
-							<div>
-								<div class="custom-control custom-switch" style="z-index: 9999;">
-									<input type="checkbox" class="custom-control-input" id="asnsfw" v-model="nsfw">
-									<label class="custom-control-label" for="asnsfw"></label>
+						<div class="border-bottom px-4 mb-0 py-2">
+							<div class="d-flex justify-content-between">
+								<div>
+									<div class="text-dark ">Contains NSFW Media</div>
+								</div>
+								<div>
+									<div class="custom-control custom-switch" style="z-index: 9999;">
+										<input type="checkbox" class="custom-control-input" id="asnsfw" v-model="nsfw">
+										<label class="custom-control-label" for="asnsfw"></label>
+									</div>
 								</div>
 							</div>
+
+							<div v-if="nsfw">
+								<textarea
+									class="form-control mt-3"
+									placeholder="Add an optional content warning or spoiler text"
+									maxlength="140"
+									v-model="spoilerText">
+								</textarea>
+
+								<p class="help-text small text-right text-muted mb-0">{{ spoilerTextLength }}/140</p>
+							</div>
 						</div>
 						<div class="border-bottom">
 							<p class="px-4 mb-0 py-2 cursor-pointer" @click="showTagCard()">Tag people</p>
@@ -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) {

+ 1 - 1
resources/assets/js/components/presenter/PhotoAlbumPresenter.vue

@@ -7,7 +7,7 @@
 			<p class="h4 font-weight-bold text-center">
 				Sensitive Content
 			</p>
-			<p class="text-center py-2">
+			<p class="text-center py-2 content-label-text">
 				{{ status.spoiler_text ? status.spoiler_text : 'This album may contain sensitive content.'}}
 			</p>
 			<p class="mb-0">

+ 1 - 1
resources/assets/js/components/presenter/PhotoPresenter.vue

@@ -7,7 +7,7 @@
 			<p class="h4 font-weight-bold text-center">
 				Sensitive Content
 			</p>
-			<p class="text-center py-2">
+			<p class="text-center py-2 content-label-text">
 				{{ status.spoiler_text ? status.spoiler_text : 'This post may contain sensitive content.'}}
 			</p>
 			<p class="mb-0">

+ 1 - 1
resources/assets/js/components/presenter/VideoPresenter.vue

@@ -7,7 +7,7 @@
 			<p class="h4 font-weight-bold text-center">
 				Sensitive Content
 			</p>
-			<p class="text-center py-2">
+			<p class="text-center py-2 content-label-text">
 				{{ status.spoiler_text ? status.spoiler_text : 'This post may contain sensitive content.'}}
 			</p>
 			<p class="mb-0">

+ 15 - 0
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%;
+		}
+	}
+}

+ 37 - 0
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%;
+		}
+	}
+}