diff --git a/app/Http/Controllers/Api/ApiV1Controller.php b/app/Http/Controllers/Api/ApiV1Controller.php index b08e29452..7711726ae 100644 --- a/app/Http/Controllers/Api/ApiV1Controller.php +++ b/app/Http/Controllers/Api/ApiV1Controller.php @@ -2177,18 +2177,26 @@ class ApiV1Controller extends Controller } } - $res = collect($res)->take($limit)->map(function($id) use($napi) { + $res = collect($res) + ->map(function($id) use($napi) { return $napi ? StatusService::get($id, false) : StatusService::getMastodon($id, false); - })->filter(function($res) { + }) + ->filter(function($res) { return $res && isset($res['account']); - })->map(function($status) use($pid) { + }) + ->filter(function($s) use($includeReblogs) { + return $includeReblogs ? true : $s['reblog'] == null; + }) + ->take($limit) + ->map(function($status) use($pid) { if($pid) { $status['favourited'] = (bool) LikeService::liked($pid, $status['id']); $status['reblogged'] = (bool) ReblogService::get($pid, $status['id']); $status['bookmarked'] = (bool) BookmarkService::get($pid, $status['id']); } return $status; - }); + }) + ->values(); $baseUrl = config('app.url') . '/api/v1/timelines/home?limit=' . $limit . '&'; $minId = $res->map(function($s) { @@ -3823,7 +3831,7 @@ class ApiV1Controller extends Controller if($follows) { HashtagService::unfollow($pid, $tag->id); HashtagFollowService::unfollow($tag->id, $pid); - HashtagUnfollowPipeline::dispatch($tag->id, $pid)->onQueue('feed'); + HashtagUnfollowPipeline::dispatch($tag->id, $pid, $tag->slug)->onQueue('feed'); $follows->delete(); } diff --git a/app/Jobs/HomeFeedPipeline/FeedInsertRemotePipeline.php b/app/Jobs/HomeFeedPipeline/FeedInsertRemotePipeline.php new file mode 100644 index 000000000..579c290a7 --- /dev/null +++ b/app/Jobs/HomeFeedPipeline/FeedInsertRemotePipeline.php @@ -0,0 +1,73 @@ +sid; + } + + /** + * Get the middleware the job should pass through. + * + * @return array + */ + public function middleware(): array + { + return [(new WithoutOverlapping("hts:feed:insert:remote:sid:{$this->sid}"))->shared()->dontRelease()]; + } + + /** + * Create a new job instance. + */ + public function __construct($sid, $pid) + { + $this->sid = $sid; + $this->pid = $pid; + } + + /** + * Execute the job. + */ + public function handle(): void + { + $ids = FollowerService::localFollowerIds($this->pid); + + foreach($ids as $id) { + HomeTimelineService::add($id, $this->sid); + } + } +} diff --git a/app/Jobs/HomeFeedPipeline/FeedRemoveRemotePipeline.php b/app/Jobs/HomeFeedPipeline/FeedRemoveRemotePipeline.php new file mode 100644 index 000000000..d9ee716ba --- /dev/null +++ b/app/Jobs/HomeFeedPipeline/FeedRemoveRemotePipeline.php @@ -0,0 +1,74 @@ +sid; + } + + /** + * Get the middleware the job should pass through. + * + * @return array + */ + public function middleware(): array + { + return [(new WithoutOverlapping("hts:feed:remove:remote:sid:{$this->sid}"))->shared()->dontRelease()]; + } + + /** + * Create a new job instance. + */ + public function __construct($sid, $pid) + { + $this->sid = $sid; + $this->pid = $pid; + } + + /** + * Execute the job. + */ + public function handle(): void + { + $ids = FollowerService::localFollowerIds($this->pid); + + foreach($ids as $id) { + HomeTimelineService::rem($id, $this->sid); + } + } +} diff --git a/app/Jobs/HomeFeedPipeline/HashtagUnfollowPipeline.php b/app/Jobs/HomeFeedPipeline/HashtagUnfollowPipeline.php index ece5dbf8f..69573f410 100644 --- a/app/Jobs/HomeFeedPipeline/HashtagUnfollowPipeline.php +++ b/app/Jobs/HomeFeedPipeline/HashtagUnfollowPipeline.php @@ -24,6 +24,7 @@ class HashtagUnfollowPipeline implements ShouldQueue protected $pid; protected $hid; + protected $slug; public $timeout = 900; public $tries = 3; @@ -33,10 +34,11 @@ class HashtagUnfollowPipeline implements ShouldQueue /** * Create a new job instance. */ - public function __construct($hid, $pid) + public function __construct($hid, $pid, $slug) { $this->hid = $hid; $this->pid = $pid; + $this->slug = $slug; } /** @@ -46,6 +48,7 @@ class HashtagUnfollowPipeline implements ShouldQueue { $hid = $this->hid; $pid = $this->pid; + $slug = $this->slug; $statusIds = HomeTimelineService::get($pid, 0, -1); @@ -60,7 +63,16 @@ class HashtagUnfollowPipeline implements ShouldQueue HomeTimelineService::rem($pid, $id); continue; } - if(!in_array($status['account']['id'], $followingIds)) { + $following = in_array($status['account']['id'], $followingIds); + if($following || !isset($status['tags'])) { + continue; + } + + $tags = collect($status['tags'])->filter(function($tag) { + return $tag['name']; + })->toArray(); + + if(in_array($slug, $tags)) { HomeTimelineService::rem($pid, $id); } } diff --git a/app/Jobs/SharePipeline/SharePipeline.php b/app/Jobs/SharePipeline/SharePipeline.php index ae184957e..4eca4e1ab 100644 --- a/app/Jobs/SharePipeline/SharePipeline.php +++ b/app/Jobs/SharePipeline/SharePipeline.php @@ -17,6 +17,7 @@ use GuzzleHttp\{Pool, Client, Promise}; use App\Util\ActivityPub\HttpSignature; use App\Services\ReblogService; use App\Services\StatusService; +use App\Jobs\HomeFeedPipeline\FeedInsertPipeline; class SharePipeline implements ShouldQueue { @@ -82,6 +83,8 @@ class SharePipeline implements ShouldQueue ] ); + FeedInsertPipeline::dispatch($status->id, $status->profile_id)->onQueue('feed'); + return $this->remoteAnnounceDeliver(); } diff --git a/app/Jobs/SharePipeline/UndoSharePipeline.php b/app/Jobs/SharePipeline/UndoSharePipeline.php index 3850a4752..1435688d9 100644 --- a/app/Jobs/SharePipeline/UndoSharePipeline.php +++ b/app/Jobs/SharePipeline/UndoSharePipeline.php @@ -17,6 +17,7 @@ use GuzzleHttp\{Pool, Client, Promise}; use App\Util\ActivityPub\HttpSignature; use App\Services\ReblogService; use App\Services\StatusService; +use App\Jobs\HomeFeedPipeline\FeedRemovePipeline; class UndoSharePipeline implements ShouldQueue { @@ -35,6 +36,8 @@ class UndoSharePipeline implements ShouldQueue $actor = $status->profile; $parent = Status::find($status->reblog_of_id); + FeedRemovePipeline::dispatch($status->id, $status->profile_id)->onQueue('feed'); + if($parent) { $target = $parent->profile_id; ReblogService::removePostReblog($parent->profile_id, $status->id); diff --git a/app/Jobs/StatusPipeline/StatusEntityLexer.php b/app/Jobs/StatusPipeline/StatusEntityLexer.php index 76d2d98d0..a6266044c 100644 --- a/app/Jobs/StatusPipeline/StatusEntityLexer.php +++ b/app/Jobs/StatusPipeline/StatusEntityLexer.php @@ -161,7 +161,6 @@ class StatusEntityLexer implements ShouldQueue if(config('exp.cached_home_timeline')) { if( $status->in_reply_to_id === null && - $status->reblog_of_id === null && in_array($status->scope, ['public', 'unlisted', 'private']) ) { FeedInsertPipeline::dispatch($status->id, $status->profile_id)->onQueue('feed'); diff --git a/app/Observers/HashtagFollowObserver.php b/app/Observers/HashtagFollowObserver.php index 822ee0805..56158c21a 100644 --- a/app/Observers/HashtagFollowObserver.php +++ b/app/Observers/HashtagFollowObserver.php @@ -31,7 +31,6 @@ class HashtagFollowObserver implements ShouldHandleEventsAfterCommit public function deleting(HashtagFollow $hashtagFollow): void { HashtagFollowService::unfollow($hashtagFollow->hashtag_id, $hashtagFollow->profile_id); - HashtagUnfollowPipeline::dispatch($hashtagFollow->hashtag_id, $hashtagFollow->profile_id); } /** @@ -48,6 +47,5 @@ class HashtagFollowObserver implements ShouldHandleEventsAfterCommit public function forceDeleted(HashtagFollow $hashtagFollow): void { HashtagFollowService::unfollow($hashtagFollow->hashtag_id, $hashtagFollow->profile_id); - HashtagUnfollowPipeline::dispatch($hashtagFollow->hashtag_id, $hashtagFollow->profile_id); } } diff --git a/app/Observers/StatusObserver.php b/app/Observers/StatusObserver.php index 9b9f8e4f1..d78585175 100644 --- a/app/Observers/StatusObserver.php +++ b/app/Observers/StatusObserver.php @@ -8,6 +8,7 @@ use Cache; use App\Models\ImportPost; use App\Services\ImportService; use App\Jobs\HomeFeedPipeline\FeedRemovePipeline; +use App\Jobs\HomeFeedPipeline\FeedRemoveRemotePipeline; class StatusObserver { @@ -66,7 +67,11 @@ class StatusObserver } if(config('exp.cached_home_timeline')) { - FeedRemovePipeline::dispatch($status->id, $status->profile_id)->onQueue('feed'); + if($status->uri) { + FeedRemoveRemotePipeline::dispatch($status->id, $status->profile_id)->onQueue('feed'); + } else { + FeedRemovePipeline::dispatch($status->id, $status->profile_id)->onQueue('feed'); + } } } diff --git a/app/Util/ActivityPub/Helpers.php b/app/Util/ActivityPub/Helpers.php index 989334926..459bda7c3 100644 --- a/app/Util/ActivityPub/Helpers.php +++ b/app/Util/ActivityPub/Helpers.php @@ -35,6 +35,7 @@ use App\Services\MediaStorageService; use App\Services\NetworkTimelineService; use App\Jobs\MediaPipeline\MediaStoragePipeline; use App\Jobs\AvatarPipeline\RemoteAvatarFetch; +use App\Jobs\HomeFeedPipeline\FeedInsertRemotePipeline; use App\Util\Media\License; use App\Models\Poll; use Illuminate\Contracts\Cache\LockTimeoutException; @@ -537,6 +538,8 @@ class Helpers { IncrementPostCount::dispatch($pid)->onQueue('low'); + FeedInsertRemotePipeline::dispatch($status->id, $pid)->onQueue('feed'); + return $status; } diff --git a/app/Util/ActivityPub/Inbox.php b/app/Util/ActivityPub/Inbox.php index 4441becfb..e97eda34d 100644 --- a/app/Util/ActivityPub/Inbox.php +++ b/app/Util/ActivityPub/Inbox.php @@ -49,6 +49,7 @@ use App\Models\Conversation; use App\Models\RemoteReport; use App\Jobs\ProfilePipeline\IncrementPostCount; use App\Jobs\ProfilePipeline\DecrementPostCount; +use App\Jobs\HomeFeedPipeline\FeedRemoveRemotePipeline; class Inbox { @@ -707,6 +708,7 @@ class Inbox if(!$status) { return; } + FeedRemoveRemotePipeline::dispatch($status->id, $status->profile_id)->onQueue('feed'); RemoteStatusDelete::dispatch($status)->onQueue('high'); return; break; @@ -803,6 +805,7 @@ class Inbox if(!$status) { return; } + FeedRemoveRemotePipeline::dispatch($status->id, $status->profile_id)->onQueue('feed'); Status::whereProfileId($profile->id) ->whereReblogOfId($status->id) ->delete();