diff --git a/app/Http/Controllers/Api/BaseApiController.php b/app/Http/Controllers/Api/BaseApiController.php index 0e62013f4..70401eba5 100644 --- a/app/Http/Controllers/Api/BaseApiController.php +++ b/app/Http/Controllers/Api/BaseApiController.php @@ -15,7 +15,8 @@ use App\{ Media, Notification, Profile, - Status + Status, + StatusArchived }; use App\Transformer\Api\{ AccountTransformer, @@ -39,6 +40,7 @@ use App\Jobs\VideoPipeline\{ use App\Services\NotificationService; use App\Services\MediaPathService; use App\Services\MediaBlocklistService; +use App\Services\StatusService; class BaseApiController extends Controller { @@ -286,4 +288,75 @@ class BaseApiController extends Controller return response()->json($res, 200, [], JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES); } + + public function archive(Request $request, $id) + { + abort_if(!$request->user(), 403); + + $status = Status::whereNull('in_reply_to_id') + ->whereNull('reblog_of_id') + ->whereProfileId($request->user()->profile_id) + ->findOrFail($id); + + if($status->scope === 'archived') { + return [200]; + } + + $archive = new StatusArchived; + $archive->status_id = $status->id; + $archive->profile_id = $status->profile_id; + $archive->original_scope = $status->scope; + $archive->save(); + + $status->scope = 'archived'; + $status->visibility = 'draft'; + $status->save(); + + StatusService::del($status->id); + + // invalidate caches + + return [200]; + } + + public function unarchive(Request $request, $id) + { + abort_if(!$request->user(), 403); + + $status = Status::whereNull('in_reply_to_id') + ->whereNull('reblog_of_id') + ->whereProfileId($request->user()->profile_id) + ->findOrFail($id); + + if($status->scope !== 'archived') { + return [200]; + } + + $archive = StatusArchived::whereStatusId($status->id) + ->whereProfileId($status->profile_id) + ->firstOrFail(); + + $status->scope = $archive->original_scope; + $status->visibility = $archive->original_scope; + $status->save(); + + $archive->delete(); + + return [200]; + } + + public function archivedPosts(Request $request) + { + abort_if(!$request->user(), 403); + + $statuses = Status::whereProfileId($request->user()->profile_id) + ->whereScope('archived') + ->orderByDesc('id') + ->simplePaginate(10); + + $fractal = new Fractal\Manager(); + $fractal->setSerializer(new ArraySerializer()); + $resource = new Fractal\Resource\Collection($statuses, new StatusStatelessTransformer()); + return $fractal->createData($resource)->toArray(); + } } diff --git a/resources/assets/js/components/PostComponent.vue b/resources/assets/js/components/PostComponent.vue index 6395318af..0ca16f10e 100644 --- a/resources/assets/js/components/PostComponent.vue +++ b/resources/assets/js/components/PostComponent.vue @@ -616,6 +616,8 @@
Block
Unblock
Report +
Archive
+
Unarchive
Delete
Cancel
@@ -1757,6 +1759,29 @@ export default { }); }, + archivePost(status) { + if(window.confirm('Are you sure you want to archive this post?') == false) { + return; + } + + axios.post('/api/pixelfed/v2/status/' + status.id + '/archive') + .then(res => { + this.$refs.ctxModal.hide(); + window.location.href = '/'; + }); + }, + + unarchivePost(status) { + if(window.confirm('Are you sure you want to unarchive this post?') == false) { + return; + } + + axios.post('/api/pixelfed/v2/status/' + status.id + '/unarchive') + .then(res => { + this.$refs.ctxModal.hide(); + }); + } + }, } diff --git a/resources/assets/js/components/Profile.vue b/resources/assets/js/components/Profile.vue index 6545a8eae..83d524369 100644 --- a/resources/assets/js/components/Profile.vue +++ b/resources/assets/js/components/Profile.vue @@ -181,64 +181,68 @@ +
-
-
- -
-
- @@ -663,6 +690,7 @@ diff --git a/resources/assets/js/components/partials/StatusCard.vue b/resources/assets/js/components/partials/StatusCard.vue index 2e5b75c0d..47aff093a 100644 --- a/resources/assets/js/components/partials/StatusCard.vue +++ b/resources/assets/js/components/partials/StatusCard.vue @@ -77,7 +77,10 @@
- +
@@ -149,9 +152,13 @@

- + + + Posted + + · Based on popular and trending content diff --git a/resources/views/site/help/sharing-media.blade.php b/resources/views/site/help/sharing-media.blade.php index f29b39d3f..d429f7406 100644 --- a/resources/views/site/help/sharing-media.blade.php +++ b/resources/views/site/help/sharing-media.blade.php @@ -32,7 +32,7 @@

-

+

+

+
+ You can archive your posts which prevents anyone from interacting or viewing it. +
+ Archived posts cannot be deleted or otherwise interacted with. You may not recieve interactions (comments, likes, shares) from other servers while a post is archived. +
+
+
+

+ +

+ +

+
+ To archive your posts: + +
+
+

+ +

+ +

+
+ To unarchive your posts: + +
+
+

+ +@endsection diff --git a/routes/web.php b/routes/web.php index 77e834b2f..21bee6aaf 100644 --- a/routes/web.php +++ b/routes/web.php @@ -200,6 +200,9 @@ Route::domain(config('pixelfed.domain.app'))->middleware(['validemail', 'twofact Route::get('discover/posts/places', 'DiscoverController@trendingPlaces'); Route::get('seasonal/yir', 'SeasonalController@getData'); Route::post('seasonal/yir', 'SeasonalController@store'); + Route::post('status/{id}/archive', 'ApiController@archive'); + Route::post('status/{id}/unarchive', 'ApiController@unarchive'); + Route::get('statuses/archives', 'ApiController@archivedPosts'); }); });