diff --git a/app/Http/Controllers/DiscoverController.php b/app/Http/Controllers/DiscoverController.php index 2277e8ee9..d6e9f1338 100644 --- a/app/Http/Controllers/DiscoverController.php +++ b/app/Http/Controllers/DiscoverController.php @@ -16,7 +16,11 @@ use App\{ }; use Auth, DB, Cache; use Illuminate\Http\Request; +use App\Services\BookmarkService; use App\Services\ConfigCacheService; +use App\Services\HashtagService; +use App\Services\LikeService; +use App\Services\ReblogService; use App\Services\StatusHashtagService; use App\Services\SnowflakeService; use App\Services\StatusService; @@ -76,10 +80,8 @@ class DiscoverController extends Controller $tag = $request->input('hashtag'); $hashtag = Hashtag::whereName($tag)->firstOrFail(); - if($user && $page == 1) { - $res['follows'] = HashtagFollow::whereUserId($user->id) - ->whereHashtagId($hashtag->id) - ->exists(); + if($user) { + $res['follows'] = HashtagService::isFollowing($user->profile_id, $hashtag->id); } $res['hashtag'] = [ 'name' => $hashtag->name, @@ -88,6 +90,12 @@ class DiscoverController extends Controller if($user) { $tags = StatusHashtagService::get($hashtag->id, $page, $end); $res['tags'] = collect($tags) + ->map(function($tag) use($user) { + $tag['status']['favourited'] = (bool) LikeService::liked($user->profile_id, $tag['status']['id']); + $tag['status']['reblogged'] = (bool) ReblogService::get($user->profile_id, $tag['status']['id']); + $tag['status']['bookmarked'] = (bool) BookmarkService::get($user->profile_id, $tag['status']['id']); + return $tag; + }) ->filter(function($tag) { if(!StatusService::get($tag['status']['id'])) { return false; diff --git a/app/Http/Controllers/HashtagFollowController.php b/app/Http/Controllers/HashtagFollowController.php index 585248abb..4554bb963 100644 --- a/app/Http/Controllers/HashtagFollowController.php +++ b/app/Http/Controllers/HashtagFollowController.php @@ -9,6 +9,7 @@ use App\{ HashtagFollow, Status }; +use App\Services\HashtagService; class HashtagFollowController extends Controller { @@ -37,9 +38,11 @@ class HashtagFollowController extends Controller if($hashtagFollow->wasRecentlyCreated) { $state = 'created'; + HashtagService::follow($profile->id, $hashtag->id); // todo: send to HashtagFollowService } else { $state = 'deleted'; + HashtagService::unfollow($profile->id, $hashtag->id); $hashtagFollow->delete(); } diff --git a/app/Services/HashtagService.php b/app/Services/HashtagService.php index 6a40595d3..de58fae59 100644 --- a/app/Services/HashtagService.php +++ b/app/Services/HashtagService.php @@ -2,12 +2,16 @@ namespace App\Services; -use Cache; +use Illuminate\Support\Facades\Cache; +use Illuminate\Support\Facades\Redis; use App\Hashtag; use App\StatusHashtag; +use App\HashtagFollow; class HashtagService { + const FOLLOW_KEY = 'pf:services:hashtag:following:'; + public static function get($id) { return Cache::remember('services:hashtag:by_id:' . $id, 3600, function() use($id) { @@ -29,4 +33,35 @@ class HashtagService { }); } + public static function isFollowing($pid, $hid) + { + $res = Redis::zscore(self::FOLLOW_KEY . $pid, $hid); + if($res) { + return true; + } + + $synced = Cache::get(self::FOLLOW_KEY . $pid . ':synced'); + if(!$synced) { + $tags = HashtagFollow::whereProfileId($pid) + ->get() + ->each(function($tag) use($pid) { + self::follow($pid, $tag->hashtag_id); + }); + Cache::set(self::FOLLOW_KEY . $pid . ':synced', true, 1209600); + + return (bool) Redis::zscore(self::FOLLOW_KEY . $pid, $hid) > 1; + } + + return false; + } + + public static function follow($pid, $hid) + { + return Redis::zadd(self::FOLLOW_KEY . $pid, $hid, $hid); + } + + public static function unfollow($pid, $hid) + { + return Redis::zrem(self::FOLLOW_KEY . $pid, $hid); + } }