mirror of
https://github.com/pixelfed/pixelfed.git
synced 2024-11-22 14:31:26 +00:00
Merge branch 'staging' of github.com:pixelfed/pixelfed into jippi-fork
This commit is contained in:
commit
091de696c2
11 changed files with 518 additions and 491 deletions
|
@ -5,6 +5,11 @@
|
|||
### Updates
|
||||
|
||||
- Update SoftwareUpdateService, add command to refresh latest versions ([632f2cb6](https://github.com/pixelfed/pixelfed/commit/632f2cb6))
|
||||
- Update Post.vue, fix cache bug ([3a27e637](https://github.com/pixelfed/pixelfed/commit/3a27e637))
|
||||
- Update StatusHashtagService, use more efficient cached count ([592c8412](https://github.com/pixelfed/pixelfed/commit/592c8412))
|
||||
- Update DiscoverController, handle discover hashtag redirects ([18382e8a](https://github.com/pixelfed/pixelfed/commit/18382e8a))
|
||||
- Update ApiV1Controller, use admin filter service ([94503a1c](https://github.com/pixelfed/pixelfed/commit/94503a1c))
|
||||
- Update SearchApiV2Service, use more efficient query ([cee618e8](https://github.com/pixelfed/pixelfed/commit/cee618e8))
|
||||
- ([](https://github.com/pixelfed/pixelfed/commit/))
|
||||
|
||||
## [v0.11.13 (2024-03-05)](https://github.com/pixelfed/pixelfed/compare/v0.11.12...v0.11.13)
|
||||
|
|
|
@ -37,6 +37,7 @@ use App\Models\Conversation;
|
|||
use App\Notification;
|
||||
use App\Profile;
|
||||
use App\Services\AccountService;
|
||||
use App\Services\AdminShadowFilterService;
|
||||
use App\Services\BookmarkService;
|
||||
use App\Services\BouncerService;
|
||||
use App\Services\CollectionService;
|
||||
|
@ -2648,7 +2649,7 @@ class ApiV1Controller extends Controller
|
|||
$domainBlocks = UserFilterService::domainBlocks($user->profile_id);
|
||||
$hideNsfw = config('instance.hide_nsfw_on_public_feeds');
|
||||
$amin = SnowflakeService::byDate(now()->subDays(config('federation.network_timeline_days_falloff')));
|
||||
|
||||
$asf = AdminShadowFilterService::getHideFromPublicFeedsList();
|
||||
if ($local && $remote) {
|
||||
$feed = Status::select(
|
||||
'id',
|
||||
|
@ -2824,6 +2825,21 @@ class ApiV1Controller extends Controller
|
|||
|
||||
return ! in_array($domain, $domainBlocks);
|
||||
})
|
||||
->filter(function ($s) use ($asf, $user) {
|
||||
if (! $asf || count($asf) === 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (in_array($s['account']['id'], $asf)) {
|
||||
if ($user->profile_id == $s['account']['id']) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
})
|
||||
->take($limit)
|
||||
->values();
|
||||
|
||||
|
|
|
@ -2,48 +2,47 @@
|
|||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\{
|
||||
DiscoverCategory,
|
||||
Follower,
|
||||
Hashtag,
|
||||
HashtagFollow,
|
||||
Instance,
|
||||
Like,
|
||||
Profile,
|
||||
Status,
|
||||
StatusHashtag,
|
||||
UserFilter
|
||||
};
|
||||
use Auth, DB, Cache;
|
||||
use Illuminate\Http\Request;
|
||||
use App\Hashtag;
|
||||
use App\Instance;
|
||||
use App\Like;
|
||||
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\StatusHashtagService;
|
||||
use App\Services\StatusService;
|
||||
use App\Services\TrendingHashtagService;
|
||||
use App\Services\UserFilterService;
|
||||
use App\Status;
|
||||
use Auth;
|
||||
use Cache;
|
||||
use DB;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class DiscoverController extends Controller
|
||||
{
|
||||
public function home(Request $request)
|
||||
{
|
||||
abort_if(! Auth::check() && config('instance.discover.public') == false, 403);
|
||||
|
||||
return view('discover.home');
|
||||
}
|
||||
|
||||
public function showTags(Request $request, $hashtag)
|
||||
{
|
||||
if ($request->user()) {
|
||||
return redirect('/i/web/hashtag/'.$hashtag.'?src=pd');
|
||||
}
|
||||
abort_if(! config('instance.discover.tags.is_public') && ! Auth::check(), 403);
|
||||
|
||||
$tag = Hashtag::whereName($hashtag)
|
||||
->orWhere('slug', $hashtag)
|
||||
->where('is_banned', '!=', true)
|
||||
->firstOrFail();
|
||||
$tagCount = StatusHashtagService::count($tag->id);
|
||||
$tagCount = $tag->cached_count ?? 0;
|
||||
|
||||
return view('discover.tags.show', compact('tag', 'tagCount'));
|
||||
}
|
||||
|
||||
|
@ -54,7 +53,7 @@ class DiscoverController extends Controller
|
|||
|
||||
$this->validate($request, [
|
||||
'hashtag' => 'required|string|min:1|max:124',
|
||||
'page' => 'nullable|integer|min:1|max:' . ($user ? 29 : 3)
|
||||
'page' => 'nullable|integer|min:1|max:'.($user ? 29 : 3),
|
||||
]);
|
||||
|
||||
$page = $request->input('page') ?? '1';
|
||||
|
@ -75,7 +74,7 @@ class DiscoverController extends Controller
|
|||
}
|
||||
$res['hashtag'] = [
|
||||
'name' => $hashtag->name,
|
||||
'url' => $hashtag->url()
|
||||
'url' => $hashtag->url(),
|
||||
];
|
||||
if ($user) {
|
||||
$tags = StatusHashtagService::get($hashtag->id, $page, $end);
|
||||
|
@ -84,18 +83,21 @@ class DiscoverController extends Controller
|
|||
$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;
|
||||
}
|
||||
|
||||
return true;
|
||||
})
|
||||
->values();
|
||||
} else {
|
||||
if ($page != 1) {
|
||||
$res['tags'] = [];
|
||||
|
||||
return $res;
|
||||
}
|
||||
$key = 'discover:tags:public_feed:'.$hashtag->id.':page:'.$page;
|
||||
|
@ -105,6 +107,7 @@ class DiscoverController extends Controller
|
|||
if (! $tag['status']['local']) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
})
|
||||
->values();
|
||||
|
@ -114,10 +117,12 @@ class DiscoverController extends Controller
|
|||
if (! StatusService::get($tag['status']['id'])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
})
|
||||
->values();
|
||||
}
|
||||
|
||||
return $res;
|
||||
}
|
||||
|
||||
|
@ -144,12 +149,13 @@ class DiscoverController extends Controller
|
|||
$ttls = [
|
||||
1 => 1500,
|
||||
31 => 14400,
|
||||
365 => 86400
|
||||
365 => 86400,
|
||||
];
|
||||
$key = ':api:discover:trending:v2.12:range:'.$days;
|
||||
|
||||
$ids = Cache::remember($key, $ttls[$days], function () use ($days) {
|
||||
$min_id = SnowflakeService::byDate(now()->subDays($days));
|
||||
|
||||
return DB::table('statuses')
|
||||
->select(
|
||||
'id',
|
||||
|
@ -165,7 +171,7 @@ class DiscoverController extends Controller
|
|||
->whereIn('type', [
|
||||
'photo',
|
||||
'photo:album',
|
||||
'video'
|
||||
'video',
|
||||
])
|
||||
->whereIsNsfw(false)
|
||||
->orderBy('likes_count', 'desc')
|
||||
|
@ -192,6 +198,7 @@ class DiscoverController extends Controller
|
|||
abort_if(! $request->user(), 403);
|
||||
|
||||
$res = TrendingHashtagService::getTrending();
|
||||
|
||||
return $res;
|
||||
}
|
||||
|
||||
|
@ -236,6 +243,7 @@ class DiscoverController extends Controller
|
|||
->map(function ($id) {
|
||||
$status = StatusService::get($id, false);
|
||||
$status['favourited'] = true;
|
||||
|
||||
return $status;
|
||||
})
|
||||
->filter(function ($post) {
|
||||
|
@ -277,6 +285,7 @@ class DiscoverController extends Controller
|
|||
if ($cc) {
|
||||
return is_string($cc) ? json_decode($cc, true) : $cc;
|
||||
}
|
||||
|
||||
return [
|
||||
'hashtags' => [
|
||||
'enabled' => false,
|
||||
|
@ -293,8 +302,8 @@ class DiscoverController extends Controller
|
|||
'server' => [
|
||||
'enabled' => false,
|
||||
'mode' => 'allowlist',
|
||||
'domains' => []
|
||||
]
|
||||
'domains' => [],
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
|
@ -321,12 +330,14 @@ class DiscoverController extends Controller
|
|||
return $post && isset($post['account']);
|
||||
})
|
||||
->values();
|
||||
|
||||
return $res;
|
||||
}
|
||||
|
||||
public function enabledFeatures(Request $request)
|
||||
{
|
||||
abort_if(! $request->user(), 404);
|
||||
|
||||
return $this->config();
|
||||
}
|
||||
|
||||
|
@ -355,6 +366,7 @@ class DiscoverController extends Controller
|
|||
if (! Instance::whereDomain($domain)->exists()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
});
|
||||
$parts = array_slice($parts, 0, 10);
|
||||
|
@ -362,6 +374,7 @@ class DiscoverController extends Controller
|
|||
$res['server']['domains'] = $d;
|
||||
}
|
||||
ConfigCacheService::put('config.discover.features', json_encode($res));
|
||||
|
||||
return $res;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,28 +2,26 @@
|
|||
|
||||
namespace App\Services;
|
||||
|
||||
use Cache;
|
||||
use Illuminate\Support\Facades\Redis;
|
||||
use App\{Hashtag, Profile, Status};
|
||||
use App\Hashtag;
|
||||
use App\Profile;
|
||||
use App\Status;
|
||||
use App\Transformer\Api\AccountTransformer;
|
||||
use App\Transformer\Api\StatusTransformer;
|
||||
use League\Fractal;
|
||||
use League\Fractal\Serializer\ArraySerializer;
|
||||
use League\Fractal\Pagination\IlluminatePaginatorAdapter;
|
||||
use App\Util\ActivityPub\Helpers;
|
||||
use Illuminate\Support\Str;
|
||||
use App\Services\AccountService;
|
||||
use App\Services\HashtagService;
|
||||
use App\Services\StatusService;
|
||||
use League\Fractal;
|
||||
use League\Fractal\Serializer\ArraySerializer;
|
||||
|
||||
|
||||
class SearchApiV2Service
|
||||
{
|
||||
private $query;
|
||||
static $mastodonMode = false;
|
||||
|
||||
public static $mastodonMode = false;
|
||||
|
||||
public static function query($query, $mastodonMode = false)
|
||||
{
|
||||
self::$mastodonMode = $mastodonMode;
|
||||
|
||||
return (new self)->run($query);
|
||||
}
|
||||
|
||||
|
@ -45,21 +43,21 @@ class SearchApiV2Service
|
|||
return [
|
||||
'accounts' => $this->accounts(),
|
||||
'hashtags' => [],
|
||||
'statuses' => []
|
||||
'statuses' => [],
|
||||
];
|
||||
break;
|
||||
case 'hashtags':
|
||||
return [
|
||||
'accounts' => [],
|
||||
'hashtags' => $this->hashtags(),
|
||||
'statuses' => []
|
||||
'statuses' => [],
|
||||
];
|
||||
break;
|
||||
case 'statuses':
|
||||
return [
|
||||
'accounts' => [],
|
||||
'hashtags' => [],
|
||||
'statuses' => $this->statuses()
|
||||
'statuses' => $this->statuses(),
|
||||
];
|
||||
break;
|
||||
}
|
||||
|
@ -69,14 +67,14 @@ class SearchApiV2Service
|
|||
return [
|
||||
'accounts' => [],
|
||||
'hashtags' => [],
|
||||
'statuses' => $this->statusesById()
|
||||
'statuses' => $this->statusesById(),
|
||||
];
|
||||
}
|
||||
|
||||
return [
|
||||
'accounts' => $this->accounts(),
|
||||
'hashtags' => $this->hashtags(),
|
||||
'statuses' => $this->statuses()
|
||||
'statuses' => $this->statuses(),
|
||||
];
|
||||
}
|
||||
|
||||
|
@ -134,31 +132,31 @@ class SearchApiV2Service
|
|||
$q = $this->query->input('q');
|
||||
$limit = $this->query->input('limit') ?? 20;
|
||||
$offset = $this->query->input('offset') ?? 0;
|
||||
$query = Str::startsWith($q, '#') ? '%' . substr($q, 1) . '%' : '%' . $q . '%';
|
||||
$query = Str::startsWith($q, '#') ? substr($q, 1).'%' : $q;
|
||||
$operator = config('database.default') === 'pgsql' ? 'ilike' : 'like';
|
||||
|
||||
return Hashtag::where('name', $operator, $query)
|
||||
->orWhere('slug', $operator, $query)
|
||||
->where(function($q) {
|
||||
return $q->where('can_search', true)
|
||||
->orWhereNull('can_search');
|
||||
})
|
||||
->orderByDesc('cached_count')
|
||||
->offset($offset)
|
||||
->limit($limit)
|
||||
->get()
|
||||
->filter(function ($tag) {
|
||||
return $tag->can_search != false;
|
||||
})
|
||||
->map(function ($tag) use ($mastodonMode) {
|
||||
$res = [
|
||||
'name' => $tag->name,
|
||||
'url' => $tag->url()
|
||||
'url' => $tag->url(),
|
||||
];
|
||||
|
||||
if (! $mastodonMode) {
|
||||
$res['history'] = [];
|
||||
$res['count'] = HashtagService::count($tag->id);
|
||||
$res['count'] = $tag->cached_count ?? 0;
|
||||
}
|
||||
|
||||
return $res;
|
||||
});
|
||||
})
|
||||
->values();
|
||||
}
|
||||
|
||||
protected function statuses()
|
||||
|
@ -194,6 +192,7 @@ class SearchApiV2Service
|
|||
}
|
||||
if (substr($query, 0, 1) === '@' && ! Str::contains($query, '.')) {
|
||||
$default['accounts'] = $this->accounts(substr($query, 1));
|
||||
|
||||
return $default;
|
||||
}
|
||||
if (Helpers::validateLocalUrl($query)) {
|
||||
|
@ -221,6 +220,7 @@ class SearchApiV2Service
|
|||
return $default;
|
||||
}
|
||||
$default['accounts'][] = $res;
|
||||
|
||||
return $default;
|
||||
} else {
|
||||
return $default;
|
||||
|
@ -239,6 +239,7 @@ class SearchApiV2Service
|
|||
return $default;
|
||||
}
|
||||
$default['accounts'][] = $res;
|
||||
|
||||
return $default;
|
||||
} else {
|
||||
return $default;
|
||||
|
@ -252,6 +253,7 @@ class SearchApiV2Service
|
|||
}
|
||||
if (in_array($s['visibility'], ['public', 'unlisted'])) {
|
||||
$default['statuses'][] = $s;
|
||||
|
||||
return $default;
|
||||
}
|
||||
}
|
||||
|
@ -286,6 +288,7 @@ class SearchApiV2Service
|
|||
return $default;
|
||||
}
|
||||
$default['statuses'][] = $note;
|
||||
|
||||
return $default;
|
||||
break;
|
||||
|
||||
|
@ -300,6 +303,7 @@ class SearchApiV2Service
|
|||
$default['accounts'][] = $mastodonMode ?
|
||||
AccountService::getMastodon($obj['id'], true) :
|
||||
AccountService::get($obj['id'], true);
|
||||
|
||||
return $default;
|
||||
break;
|
||||
|
||||
|
@ -333,14 +337,14 @@ class SearchApiV2Service
|
|||
return [
|
||||
'accounts' => [],
|
||||
'hashtags' => [],
|
||||
'statuses' => []
|
||||
'statuses' => [],
|
||||
];
|
||||
}
|
||||
|
||||
$res = [
|
||||
'accounts' => [],
|
||||
'hashtags' => [],
|
||||
'statuses' => [$status]
|
||||
'statuses' => [$status],
|
||||
];
|
||||
|
||||
return $res;
|
||||
|
@ -359,17 +363,18 @@ class SearchApiV2Service
|
|||
return [
|
||||
'accounts' => [],
|
||||
'hashtags' => [],
|
||||
'statuses' => []
|
||||
'statuses' => [],
|
||||
];
|
||||
}
|
||||
|
||||
$fractal = new Fractal\Manager();
|
||||
$fractal->setSerializer(new ArraySerializer());
|
||||
$resource = new Fractal\Resource\Item($profile, new AccountTransformer());
|
||||
|
||||
return [
|
||||
'accounts' => [$fractal->createData($resource)->toArray()],
|
||||
'hashtags' => [],
|
||||
'statuses' => []
|
||||
'statuses' => [],
|
||||
];
|
||||
}
|
||||
|
||||
|
@ -384,18 +389,18 @@ class SearchApiV2Service
|
|||
return [
|
||||
'accounts' => [],
|
||||
'hashtags' => [],
|
||||
'statuses' => []
|
||||
'statuses' => [],
|
||||
];
|
||||
}
|
||||
|
||||
$fractal = new Fractal\Manager();
|
||||
$fractal->setSerializer(new ArraySerializer());
|
||||
$resource = new Fractal\Resource\Item($profile, new AccountTransformer());
|
||||
|
||||
return [
|
||||
'accounts' => [$fractal->createData($resource)->toArray()],
|
||||
'hashtags' => [],
|
||||
'statuses' => []
|
||||
'statuses' => [],
|
||||
];
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -2,17 +2,15 @@
|
|||
|
||||
namespace App\Services;
|
||||
|
||||
use Cache;
|
||||
use Illuminate\Support\Facades\Redis;
|
||||
use App\{Status, StatusHashtag};
|
||||
use App\Transformer\Api\StatusHashtagTransformer;
|
||||
use App\Hashtag;
|
||||
use App\Status;
|
||||
use App\StatusHashtag;
|
||||
use App\Transformer\Api\HashtagTransformer;
|
||||
use League\Fractal;
|
||||
use League\Fractal\Serializer\ArraySerializer;
|
||||
use League\Fractal\Pagination\IlluminatePaginatorAdapter;
|
||||
|
||||
class StatusHashtagService {
|
||||
|
||||
class StatusHashtagService
|
||||
{
|
||||
const CACHE_KEY = 'pf:services:status-hashtag:collection:';
|
||||
|
||||
public static function get($id, $page = 1, $stop = 9)
|
||||
|
@ -55,6 +53,7 @@ class StatusHashtagService {
|
|||
foreach ($ids as $key) {
|
||||
self::set($id, $key);
|
||||
}
|
||||
|
||||
return $ids;
|
||||
}
|
||||
|
||||
|
@ -70,11 +69,12 @@ class StatusHashtagService {
|
|||
|
||||
public static function count($id)
|
||||
{
|
||||
$key = 'pf:services:status-hashtag:count:' . $id;
|
||||
$ttl = now()->addMinutes(5);
|
||||
return Cache::remember($key, $ttl, function() use($id) {
|
||||
return StatusHashtag::whereHashtagId($id)->has('media')->count();
|
||||
});
|
||||
$cc = Hashtag::find($id);
|
||||
if (! $cc) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return $cc->cached_count ?? 0;
|
||||
}
|
||||
|
||||
public static function getStatus($statusId, $hashtagId)
|
||||
|
@ -92,6 +92,7 @@ class StatusHashtagService {
|
|||
$fractal = new Fractal\Manager();
|
||||
$fractal->setSerializer(new ArraySerializer());
|
||||
$resource = new Fractal\Resource\Collection($status->hashtags, new HashtagTransformer());
|
||||
|
||||
return $fractal->createData($resource)->toArray();
|
||||
}
|
||||
}
|
||||
|
|
BIN
public/js/manifest.js
vendored
BIN
public/js/manifest.js
vendored
Binary file not shown.
BIN
public/js/post.chunk.5ff16664f9adb901.js
vendored
BIN
public/js/post.chunk.5ff16664f9adb901.js
vendored
Binary file not shown.
BIN
public/js/post.chunk.9184101a2b809af1.js
vendored
Normal file
BIN
public/js/post.chunk.9184101a2b809af1.js
vendored
Normal file
Binary file not shown.
Binary file not shown.
|
@ -171,7 +171,7 @@
|
|||
}
|
||||
},
|
||||
|
||||
beforeMount() {
|
||||
created() {
|
||||
this.init();
|
||||
},
|
||||
|
||||
|
@ -181,20 +181,7 @@
|
|||
|
||||
methods: {
|
||||
init() {
|
||||
if(this.cachedStatus && this.cachedProfile) {
|
||||
this.post = this.cachedStatus;
|
||||
this.media = this.post.media_attachments;
|
||||
this.profile = this.post.account;
|
||||
this.user = this.cachedProfile;
|
||||
if(this.post.in_reply_to_id) {
|
||||
this.fetchReply();
|
||||
} else {
|
||||
this.isReply = false;
|
||||
this.fetchRelationship();
|
||||
}
|
||||
} else {
|
||||
this.fetchSelf();
|
||||
}
|
||||
},
|
||||
|
||||
fetchSelf() {
|
||||
|
|
Loading…
Reference in a new issue