Merge pull request #3194 from pixelfed/staging

Staging
This commit is contained in:
daniel 2022-01-28 22:20:38 -07:00 committed by GitHub
commit a2c56c4e71
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
26 changed files with 228 additions and 74 deletions

View file

@ -19,6 +19,14 @@
- Updated ApiV1Controller, improve follow count cache invalidation. ([4b6effb9](https://github.com/pixelfed/pixelfed/commit/4b6effb9)) - Updated ApiV1Controller, improve follow count cache invalidation. ([4b6effb9](https://github.com/pixelfed/pixelfed/commit/4b6effb9))
- Updated web routes, fix atom feeds for account usernames containing a dot. ([8c54ab57](https://github.com/pixelfed/pixelfed/commit/8c54ab57)) - Updated web routes, fix atom feeds for account usernames containing a dot. ([8c54ab57](https://github.com/pixelfed/pixelfed/commit/8c54ab57))
- Updated atom feeds, include media alt text. Fixes #3184. ([5d9b6863](https://github.com/pixelfed/pixelfed/commit/5d9b6863)) - Updated atom feeds, include media alt text. Fixes #3184. ([5d9b6863](https://github.com/pixelfed/pixelfed/commit/5d9b6863))
- Updated ApiV1Controller, add custom_emoji endpoint. ([16e72518](https://github.com/pixelfed/pixelfed/commit/16e72518))
- Updated InternalApiController, redirect remote post and profiles to Metro 2.0. ([3c35158e](https://github.com/pixelfed/pixelfed/commit/3c35158e))
- Updated BaseApiController, improve favourites endpoint. ([f063cb01](https://github.com/pixelfed/pixelfed/commit/f063cb01))
- Updated ApiV1Controller, invalidate status reply cache on new reply. ([3c261bbf](https://github.com/pixelfed/pixelfed/commit/3c261bbf))
- Updated PublicApiController, add bookmark state to timeline endpoints. ([c0b1e042](https://github.com/pixelfed/pixelfed/commit/c0b1e042))
- Updated ApiV1Controller, fix private status replies returning 404. ([73226360](https://github.com/pixelfed/pixelfed/commit/73226360))
- Updated StatusService, use BookmarkService for bookmarked state. ([a7d71551](https://github.com/pixelfed/pixelfed/commit/a7d71551))
- Updated Apis, added ReblogService to improve reblogged state for api entities ([6cfd6be5](https://github.com/pixelfed/pixelfed/commit/6cfd6be5))
- ([](https://github.com/pixelfed/pixelfed/commit/)) - ([](https://github.com/pixelfed/pixelfed/commit/))
## [v0.11.2 (2022-01-09)](https://github.com/pixelfed/pixelfed/compare/v0.11.1...v0.11.2) ## [v0.11.2 (2022-01-09)](https://github.com/pixelfed/pixelfed/compare/v0.11.1...v0.11.2)

View file

@ -360,6 +360,7 @@ class AdminController extends Controller
if($request->has('cc')) { if($request->has('cc')) {
Cache::forget('pf:admin:custom_emoji:stats'); Cache::forget('pf:admin:custom_emoji:stats');
Cache::forget('pf:custom_emoji');
return redirect(route('admin.custom-emoji')); return redirect(route('admin.custom-emoji'));
} }
@ -463,6 +464,7 @@ class AdminController extends Controller
$request->emoji->storeAs('public/emoji', $fileName); $request->emoji->storeAs('public/emoji', $fileName);
$emoji->media_path = 'emoji/' . $fileName; $emoji->media_path = 'emoji/' . $fileName;
$emoji->save(); $emoji->save();
Cache::forget('pf:custom_emoji');
return redirect(route('admin.custom-emoji')); return redirect(route('admin.custom-emoji'));
} }
@ -471,6 +473,7 @@ class AdminController extends Controller
abort_unless(config('federation.custom_emoji.enabled'), 404); abort_unless(config('federation.custom_emoji.enabled'), 404);
$emoji = CustomEmoji::findOrFail($id); $emoji = CustomEmoji::findOrFail($id);
Storage::delete("public/{$emoji->media_path}"); Storage::delete("public/{$emoji->media_path}");
Cache::forget('pf:custom_emoji');
$emoji->delete(); $emoji->delete();
return redirect(route('admin.custom-emoji')); return redirect(route('admin.custom-emoji'));
} }

View file

@ -65,6 +65,7 @@ use App\Services\{
NotificationService, NotificationService,
MediaPathService, MediaPathService,
PublicTimelineService, PublicTimelineService,
ReblogService,
RelationshipService, RelationshipService,
SearchApiV2Service, SearchApiV2Service,
StatusService, StatusService,
@ -77,6 +78,7 @@ use App\Util\Localization\Localization;
use App\Util\Media\License; use App\Util\Media\License;
use App\Jobs\MediaPipeline\MediaSyncLicensePipeline; use App\Jobs\MediaPipeline\MediaSyncLicensePipeline;
use App\Services\DiscoverService; use App\Services\DiscoverService;
use App\Services\CustomEmojiService;
class ApiV1Controller extends Controller class ApiV1Controller extends Controller
{ {
@ -920,7 +922,7 @@ class ApiV1Controller extends Controller
*/ */
public function customEmojis() public function customEmojis()
{ {
return response()->json([]); return response(CustomEmojiService::all())->header('Content-Type', 'application/json');
} }
/** /**
@ -1645,6 +1647,7 @@ class ApiV1Controller extends Controller
if($pid) { if($pid) {
$status['favourited'] = (bool) LikeService::liked($pid, $s['id']); $status['favourited'] = (bool) LikeService::liked($pid, $s['id']);
$status['reblogged'] = (bool) ReblogService::get($pid, $status['id']);
} }
return $status; return $status;
}) })
@ -1675,6 +1678,7 @@ class ApiV1Controller extends Controller
if($pid) { if($pid) {
$status['favourited'] = (bool) LikeService::liked($pid, $s['id']); $status['favourited'] = (bool) LikeService::liked($pid, $s['id']);
$status['reblogged'] = (bool) ReblogService::get($pid, $status['id']);
} }
return $status; return $status;
}) })
@ -1797,6 +1801,7 @@ class ApiV1Controller extends Controller
if($user) { if($user) {
$status['favourited'] = (bool) LikeService::liked($user->profile_id, $k); $status['favourited'] = (bool) LikeService::liked($user->profile_id, $k);
$status['reblogged'] = (bool) ReblogService::get($user->profile_id, $status['id']);
} }
return $status; return $status;
}) })
@ -1838,7 +1843,7 @@ class ApiV1Controller extends Controller
} }
$res['favourited'] = LikeService::liked($user->profile_id, $res['id']); $res['favourited'] = LikeService::liked($user->profile_id, $res['id']);
$res['reblogged'] = false; $res['reblogged'] = ReblogService::get($user->profile_id, $res['id']);
return response()->json($res); return response()->json($res);
} }
@ -2109,6 +2114,7 @@ class ApiV1Controller extends Controller
$status->in_reply_to_profile_id = $parent->profile_id; $status->in_reply_to_profile_id = $parent->profile_id;
$status->save(); $status->save();
StatusService::del($parent->id); StatusService::del($parent->id);
Cache::forget('status:replies:all:' . $parent->id);
} }
if($ids) { if($ids) {
@ -2236,7 +2242,7 @@ class ApiV1Controller extends Controller
} }
StatusService::del($status->id); StatusService::del($status->id);
ReblogService::add($user->profile_id, $status->id);
$res = StatusService::getMastodon($status->id); $res = StatusService::getMastodon($status->id);
$res['reblogged'] = true; $res['reblogged'] = true;
@ -2276,6 +2282,7 @@ class ApiV1Controller extends Controller
} }
UndoSharePipeline::dispatch($reblog); UndoSharePipeline::dispatch($reblog);
ReblogService::del($user->profile_id, $status->id);
$res = StatusService::getMastodon($status->id); $res = StatusService::getMastodon($status->id);
$res['reblogged'] = true; $res['reblogged'] = true;
@ -2512,12 +2519,25 @@ class ApiV1Controller extends Controller
$limit = $request->input('limit', 3); $limit = $request->input('limit', 3);
$pid = $request->user()->profile_id; $pid = $request->user()->profile_id;
$status = StatusService::getMastodon($id); $status = StatusService::getMastodon($id, false);
abort_if(!$status || !in_array($status['visibility'], ['public', 'unlisted']), 404); abort_if(!$status, 404);
if($status['visibility'] == 'private') {
if($pid != $status['account']['id']) {
abort_unless(FollowerService::follows($pid, $status['account']['id']), 404);
}
}
$sortBy = $request->input('sort', 'all'); $sortBy = $request->input('sort', 'all');
if($sortBy == 'all' && $status['replies_count'] && $request->has('refresh_cache')) {
if(!Cache::has('status:replies:all-rc:' . $id)) {
Cache::forget('status:replies:all:' . $id);
Cache::put('status:replies:all-rc:' . $id, true, 300);
}
}
if($sortBy == 'all' && !$request->has('cursor')) { if($sortBy == 'all' && !$request->has('cursor')) {
$ids = Cache::remember('status:replies:all:' . $id, 86400, function() use($id) { $ids = Cache::remember('status:replies:all:' . $id, 86400, function() use($id) {
return DB::table('statuses') return DB::table('statuses')

View file

@ -259,27 +259,29 @@ class BaseApiController extends Controller
public function accountLikes(Request $request) public function accountLikes(Request $request)
{ {
$user = $request->user();
abort_if(!$request->user(), 403); abort_if(!$request->user(), 403);
$this->validate($request, [
'page' => 'sometimes|int|min:1|max:20',
'limit' => 'sometimes|int|min:1|max:10'
]);
$limit = 10; $user = $request->user();
$page = (int) $request->input('page', 1); $limit = $request->input('limit', 10);
if($page > 20) { $res = \DB::table('likes')
return []; ->whereProfileId($user->profile_id)
}
$favourites = $user->profile->likes()
->latest() ->latest()
->simplePaginate($limit) ->simplePaginate($limit)
->pluck('status_id'); ->map(function($id) {
$status = StatusService::get($id->status_id, false);
$statuses = Status::find($favourites)->reverse(); $status['favourited'] = true;
return $status;
$resource = new Fractal\Resource\Collection($statuses, new StatusStatelessTransformer()); })
$res = $this->fractal->createData($resource)->toArray(); ->filter(function($post) {
return $post && isset($post['account']);
return response()->json($res, 200, [], JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES); })
->values();
return response()->json($res);
} }
public function archive(Request $request, $id) public function archive(Request $request, $id)

View file

@ -6,6 +6,7 @@ use App\Bookmark;
use App\Status; use App\Status;
use Auth; use Auth;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use App\Services\BookmarkService;
class BookmarkController extends Controller class BookmarkController extends Controller
{ {
@ -28,7 +29,10 @@ class BookmarkController extends Controller
); );
if (!$bookmark->wasRecentlyCreated) { if (!$bookmark->wasRecentlyCreated) {
BookmarkService::del($profile->id, $status->id);
$bookmark->delete(); $bookmark->delete();
} else {
BookmarkService::add($profile->id, $status->id);
} }
if ($request->ajax()) { if ($request->ajax()) {

View file

@ -43,6 +43,7 @@ use App\Services\SnowflakeService;
use App\Services\StatusService; use App\Services\StatusService;
use App\Services\UserFilterService; use App\Services\UserFilterService;
use App\Services\DiscoverService; use App\Services\DiscoverService;
use App\Services\BookmarkService;
class InternalApiController extends Controller class InternalApiController extends Controller
{ {
@ -316,16 +317,21 @@ class InternalApiController extends Controller
public function bookmarks(Request $request) public function bookmarks(Request $request)
{ {
$res = Bookmark::whereProfileId($request->user()->profile_id) $pid = $request->user()->profile_id;
$res = Bookmark::whereProfileId($pid)
->orderByDesc('created_at') ->orderByDesc('created_at')
->simplePaginate(10) ->simplePaginate(10)
->map(function($bookmark) { ->map(function($bookmark) use($pid) {
$status = StatusService::get($bookmark->status_id); $status = StatusService::get($bookmark->status_id, false);
$status['bookmarked_at'] = $bookmark->created_at->format('c'); $status['bookmarked_at'] = $bookmark->created_at->format('c');
if($status) {
BookmarkService::add($pid, $status['id']);
}
return $status; return $status;
}) })
->filter(function($bookmark) { ->filter(function($bookmark) {
return isset($bookmark['id']); return $bookmark && isset($bookmark['id']);
}) })
->values(); ->values();
@ -410,26 +416,12 @@ class InternalApiController extends Controller
public function remoteProfile(Request $request, $id) public function remoteProfile(Request $request, $id)
{ {
$profile = Profile::whereNull('status') return redirect('/i/web/profile/' . $id);
->whereNotNull('domain')
->findOrFail($id);
$user = Auth::user();
return view('profile.remote', compact('profile', 'user'));
} }
public function remoteStatus(Request $request, $profileId, $statusId) public function remoteStatus(Request $request, $profileId, $statusId)
{ {
$user = Profile::whereNull('status') return redirect('/i/web/post/' . $statusId);
->whereNotNull('domain')
->findOrFail($profileId);
$status = Status::whereProfileId($user->id)
->whereNull('reblog_of_id')
->whereIn('visibility', ['public', 'unlisted'])
->findOrFail($statusId);
$template = $status->in_reply_to_id ? 'status.reply' : 'status.remote';
return view($template, compact('user', 'status'));
} }
public function requestEmailVerification(Request $request) public function requestEmailVerification(Request $request)

View file

@ -27,10 +27,12 @@ use App\Transformer\Api\{
}; };
use App\Services\{ use App\Services\{
AccountService, AccountService,
BookmarkService,
FollowerService, FollowerService,
LikeService, LikeService,
PublicTimelineService, PublicTimelineService,
ProfileService, ProfileService,
ReblogService,
RelationshipService, RelationshipService,
StatusService, StatusService,
SnowflakeService, SnowflakeService,
@ -327,6 +329,8 @@ class PublicApiController extends Controller
return false; return false;
} }
$status['favourited'] = (bool) LikeService::liked($user->profile_id, $s->id); $status['favourited'] = (bool) LikeService::liked($user->profile_id, $s->id);
$status['bookmarked'] = (bool) BookmarkService::get($user->profile_id, $s->id);
$status['reblogged'] = (bool) ReblogService::get($user->profile_id, $s->id);
return $status; return $status;
}) })
->filter(function($s) use($filtered) { ->filter(function($s) use($filtered) {
@ -369,6 +373,8 @@ class PublicApiController extends Controller
return false; return false;
} }
$status['favourited'] = (bool) LikeService::liked($user->profile_id, $s->id); $status['favourited'] = (bool) LikeService::liked($user->profile_id, $s->id);
$status['bookmarked'] = (bool) BookmarkService::get($user->profile_id, $s->id);
$status['reblogged'] = (bool) ReblogService::get($user->profile_id, $s->id);
return $status; return $status;
}) })
->filter(function($s) use($filtered) { ->filter(function($s) use($filtered) {
@ -398,6 +404,8 @@ class PublicApiController extends Controller
$status = StatusService::get($k); $status = StatusService::get($k);
if($user) { if($user) {
$status['favourited'] = (bool) LikeService::liked($user->profile_id, $k); $status['favourited'] = (bool) LikeService::liked($user->profile_id, $k);
$status['bookmarked'] = (bool) BookmarkService::get($user->profile_id, $k);
$status['reblogged'] = (bool) ReblogService::get($user->profile_id, $k);
$status['relationship'] = RelationshipService::get($user->profile_id, $status['account']['id']); $status['relationship'] = RelationshipService::get($user->profile_id, $status['account']['id']);
} }
return $status; return $status;
@ -481,7 +489,7 @@ class PublicApiController extends Controller
if($min || $max) { if($min || $max) {
$dir = $min ? '>' : '<'; $dir = $min ? '>' : '<';
$id = $min ?? $max; $id = $min ?? $max;
$timeline = Status::select( return Status::select(
'id', 'id',
'uri', 'uri',
'caption', 'caption',
@ -508,13 +516,27 @@ class PublicApiController extends Controller
->with('profile', 'hashtags', 'mentions') ->with('profile', 'hashtags', 'mentions')
->where('id', $dir, $id) ->where('id', $dir, $id)
->whereIn('profile_id', $following) ->whereIn('profile_id', $following)
->whereNotIn('profile_id', $filtered)
->whereIn('visibility',['public', 'unlisted', 'private']) ->whereIn('visibility',['public', 'unlisted', 'private'])
->orderBy('created_at', 'desc') ->orderBy('created_at', 'desc')
->limit($limit) ->limit($limit)
->get(); ->get()
->map(function($s) use ($user) {
$status = StatusService::get($s->id);
if(!$status) {
return false;
}
$status['favourited'] = (bool) LikeService::liked($user->profile_id, $s->id);
$status['bookmarked'] = (bool) BookmarkService::get($user->profile_id, $s->id);
$status['reblogged'] = (bool) ReblogService::get($user->profile_id, $s->id);
return $status;
})
->filter(function($s) use($filtered) {
return $s && in_array($s['account']['id'], $filtered) == false;
})
->values()
->toArray();
} else { } else {
$timeline = Status::select( return Status::select(
'id', 'id',
'uri', 'uri',
'caption', 'caption',
@ -540,15 +562,26 @@ class PublicApiController extends Controller
}) })
->with('profile', 'hashtags', 'mentions') ->with('profile', 'hashtags', 'mentions')
->whereIn('profile_id', $following) ->whereIn('profile_id', $following)
->whereNotIn('profile_id', $filtered)
->whereIn('visibility',['public', 'unlisted', 'private']) ->whereIn('visibility',['public', 'unlisted', 'private'])
->orderBy('created_at', 'desc') ->orderBy('created_at', 'desc')
->simplePaginate($limit); ->limit($limit)
->get()
->map(function($s) use ($user) {
$status = StatusService::get($s->id);
if(!$status) {
return false;
}
$status['favourited'] = (bool) LikeService::liked($user->profile_id, $s->id);
$status['bookmarked'] = (bool) BookmarkService::get($user->profile_id, $s->id);
$status['reblogged'] = (bool) ReblogService::get($user->profile_id, $s->id);
return $status;
})
->filter(function($s) use($filtered) {
return $s && in_array($s['account']['id'], $filtered) == false;
})
->values()
->toArray();
} }
$fractal = new Fractal\Resource\Collection($timeline, new StatusTransformer());
$res = $this->fractal->createData($fractal)->toArray();
return response()->json($res);
} }
public function networkTimelineApi(Request $request) public function networkTimelineApi(Request $request)
@ -595,6 +628,8 @@ class PublicApiController extends Controller
->map(function($s) use ($user) { ->map(function($s) use ($user) {
$status = StatusService::get($s->id); $status = StatusService::get($s->id);
$status['favourited'] = (bool) LikeService::liked($user->profile_id, $s->id); $status['favourited'] = (bool) LikeService::liked($user->profile_id, $s->id);
$status['bookmarked'] = (bool) BookmarkService::get($user->profile_id, $s->id);
$status['reblogged'] = (bool) ReblogService::get($user->profile_id, $s->id);
return $status; return $status;
}); });
$res = $timeline->toArray(); $res = $timeline->toArray();
@ -618,6 +653,8 @@ class PublicApiController extends Controller
->map(function($s) use ($user) { ->map(function($s) use ($user) {
$status = StatusService::get($s->id); $status = StatusService::get($s->id);
$status['favourited'] = (bool) LikeService::liked($user->profile_id, $s->id); $status['favourited'] = (bool) LikeService::liked($user->profile_id, $s->id);
$status['bookmarked'] = (bool) BookmarkService::get($user->profile_id, $s->id);
$status['reblogged'] = (bool) ReblogService::get($user->profile_id, $s->id);
return $status; return $status;
}); });
$res = $timeline->toArray(); $res = $timeline->toArray();

View file

@ -25,6 +25,7 @@ use Illuminate\Support\Str;
use App\Services\HashidService; use App\Services\HashidService;
use App\Services\StatusService; use App\Services\StatusService;
use App\Util\Media\License; use App\Util\Media\License;
use App\Services\ReblogService;
class StatusController extends Controller class StatusController extends Controller
{ {
@ -245,6 +246,7 @@ class StatusController extends Controller
->get(); ->get();
foreach ($shares as $share) { foreach ($shares as $share) {
UndoSharePipeline::dispatch($share); UndoSharePipeline::dispatch($share);
ReblogService::del($profile->id, $status->id);
$count--; $count--;
} }
} else { } else {
@ -255,6 +257,7 @@ class StatusController extends Controller
$share->save(); $share->save();
$count++; $count++;
SharePipeline::dispatch($share); SharePipeline::dispatch($share);
ReblogService::add($profile->id, $status->id);
} }
Cache::forget('status:'.$status->id.':sharedby:userid:'.$user->id); Cache::forget('status:'.$status->id.':sharedby:userid:'.$user->id);

View file

@ -0,0 +1,31 @@
<?php
namespace App\Services;
use App\Bookmark;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Redis;
class BookmarkService
{
const CACHE_KEY = 'pf:services:bookmarks:';
public static function get($profileId, $statusId)
{
if (!Redis::zcard(self::CACHE_KEY . $profileId)) {
return false;
}
return Redis::zscore(self::CACHE_KEY . $profileId, $statusId) != null;
}
public static function add($profileId, $statusId)
{
return Redis::zadd(self::CACHE_KEY . $profileId, $statusId, $statusId);
}
public static function del($profileId, $statusId)
{
return Redis::zrem(self::CACHE_KEY . $profileId, $statusId);
}
}

View file

@ -71,8 +71,8 @@ class CustomEmojiService
$emoji->save(); $emoji->save();
$name = str_replace(':', '', $json['name']); $name = str_replace(':', '', $json['name']);
Cache::forget('pf:custom_emoji');
Cache::forget('pf:custom_emoji:' . $name); Cache::forget('pf:custom_emoji:' . $name);
if($id) { if($id) {
StatusService::del($id); StatusService::del($id);
} }
@ -104,4 +104,28 @@ class CustomEmojiService
return true; return true;
} }
public static function all()
{
return Cache::rememberForever('pf:custom_emoji', function() {
$pgsql = config('database.default') === 'pgsql';
return CustomEmoji::when(!$pgsql, function($q, $pgsql) {
return $q->groupBy('shortcode');
})
->get()
->map(function($emojo) {
$url = url('storage/' . $emojo->media_path);
return [
'shortcode' => str_replace(':', '', $emojo->shortcode),
'url' => $url,
'static_path' => $url,
'visible_in_picker' => $emojo->disabled == false
];
})
->when($pgsql, function($collection) {
return $collection->unique('shortcode');
})
->toJson(JSON_UNESCAPED_SLASHES);
});
}
} }

View file

@ -0,0 +1,29 @@
<?php
namespace App\Services;
use Illuminate\Support\Facades\Redis;
class ReblogService
{
const CACHE_KEY = 'pf:services:reblogs:';
public static function get($profileId, $statusId)
{
if (!Redis::zcard(self::CACHE_KEY . $profileId)) {
return false;
}
return Redis::zscore(self::CACHE_KEY . $profileId, $statusId) != null;
}
public static function add($profileId, $statusId)
{
return Redis::zadd(self::CACHE_KEY . $profileId, $statusId, $statusId);
}
public static function del($profileId, $statusId)
{
return Redis::zrem(self::CACHE_KEY . $profileId, $statusId);
}
}

View file

@ -165,20 +165,14 @@ class StatusService
public static function isShared($id, $pid = null) public static function isShared($id, $pid = null)
{ {
return $pid ? return $pid ?
DB::table('statuses') ReblogService::get($pid, $id) :
->where('reblog_of_id', $id)
->where('profile_id', $pid)
->exists() :
false; false;
} }
public static function isBookmarked($id, $pid = null) public static function isBookmarked($id, $pid = null)
{ {
return $pid ? return $pid ?
DB::table('bookmarks') BookmarkService::get($pid, $id) :
->where('status_id', $id)
->where('profile_id', $pid)
->exists() :
false; false;
} }
} }

View file

@ -17,13 +17,15 @@ use App\Services\ProfileService;
use Illuminate\Support\Str; use Illuminate\Support\Str;
use App\Services\PollService; use App\Services\PollService;
use App\Models\CustomEmoji; use App\Models\CustomEmoji;
use App\Services\BookmarkService;
class StatusTransformer extends Fractal\TransformerAbstract class StatusTransformer extends Fractal\TransformerAbstract
{ {
public function transform(Status $status) public function transform(Status $status)
{ {
$pid = request()->user()->profile_id;
$taggedPeople = MediaTagService::get($status->id); $taggedPeople = MediaTagService::get($status->id);
$poll = $status->type === 'poll' ? PollService::get($status->id, request()->user()->profile_id) : null; $poll = $status->type === 'poll' ? PollService::get($status->id, $pid) : null;
return [ return [
'_v' => 1, '_v' => 1,
@ -69,6 +71,7 @@ class StatusTransformer extends Fractal\TransformerAbstract
'account' => ProfileService::get($status->profile_id), 'account' => ProfileService::get($status->profile_id),
'tags' => StatusHashtagService::statusTags($status->id), 'tags' => StatusHashtagService::statusTags($status->id),
'poll' => $poll, 'poll' => $poll,
'bookmarked' => BookmarkService::get($pid, $status->id),
]; ];
} }
} }

Binary file not shown.

BIN
public/js/profile.js vendored

Binary file not shown.

BIN
public/js/rempos.js vendored

Binary file not shown.

BIN
public/js/rempro.js vendored

Binary file not shown.

BIN
public/js/spa.js vendored

Binary file not shown.

BIN
public/js/status.js vendored

Binary file not shown.

BIN
public/js/timeline.js vendored

Binary file not shown.

Binary file not shown.

View file

@ -10,6 +10,7 @@
"shared": "Shared", "shared": "Shared",
"shares": "Shares", "shares": "Shares",
"unshare": "Unshare", "unshare": "Unshare",
"bookmark": "Bookmark",
"cancel": "Cancel", "cancel": "Cancel",
"copyLink": "Copy Link", "copyLink": "Copy Link",
"delete": "Delete", "delete": "Delete",

View file

@ -13,6 +13,7 @@ return [
'shared' => 'Shared', 'shared' => 'Shared',
'shares' => 'Shares', 'shares' => 'Shares',
'unshare' => 'Unshare', 'unshare' => 'Unshare',
'bookmark' => 'Bookmark',
'cancel' => 'Cancel', 'cancel' => 'Cancel',
'copyLink' => 'Copy Link', 'copyLink' => 'Copy Link',

View file

@ -1,6 +1,6 @@
<nav class="navbar navbar-expand navbar-light navbar-laravel shadow-none border-bottom sticky-top py-1"> <nav class="navbar navbar-expand navbar-light navbar-laravel shadow-none border-bottom sticky-top py-1">
<div class="container"> <div class="container">
<a class="navbar-brand d-flex align-items-center" href="{{ route('timeline.personal') }}" title="Logo"> <a class="navbar-brand d-flex align-items-center" href="/" title="Logo">
<img src="/img/pixelfed-icon-color.svg" height="30px" class="px-2" loading="eager" alt="Pixelfed logo"> <img src="/img/pixelfed-icon-color.svg" height="30px" class="px-2" loading="eager" alt="Pixelfed logo">
<span class="font-weight-bold mb-0 d-none d-sm-block" style="font-size:20px;">{{ config_cache('app.name') }}</span> <span class="font-weight-bold mb-0 d-none d-sm-block" style="font-size:20px;">{{ config_cache('app.name') }}</span>
</a> </a>
@ -18,13 +18,13 @@
<ul class="navbar-nav ml-auto"> <ul class="navbar-nav ml-auto">
<li> <li>
<a class="nav-link font-weight-bold text-dark" href="{{ route('login') }}" title="Login"> <a class="nav-link font-weight-bold text-dark" href="/login" title="Login">
{{ __('Login') }} {{ __('Login') }}
</a> </a>
</li> </li>
@if(config_cache('pixelfed.open_registration') && in_array(config_cache('system.user_mode'), ['default', 'admin'])) @if(config_cache('pixelfed.open_registration') && in_array(config_cache('system.user_mode'), ['default', 'admin']))
<li> <li>
<a class="ml-3 nav-link font-weight-bold text-dark" href="{{ route('register') }}" title="Register"> <a class="ml-3 nav-link font-weight-bold text-dark" href="/register" title="Register">
{{ __('Register') }} {{ __('Register') }}
</a> </a>
</li> </li>
@ -71,13 +71,13 @@
</span> </span>
My Feed My Feed
</a> </a>
<a class="dropdown-item lead" href="{{route('timeline.public')}}"> <a class="dropdown-item lead" href="/i/web/timeline/local">
<span style="width: 50px;margin-right:14px;"> <span style="width: 50px;margin-right:14px;">
<span class="fal fa-stream text-lighter fa-lg"></span> <span class="fal fa-stream text-lighter fa-lg"></span>
</span> </span>
Public Feed Public Feed
</a> </a>
<a class="dropdown-item lead" href="{{route('timeline.network')}}"> <a class="dropdown-item lead" href="/i/web/timeline/global">
<span style="width: 50px;margin-right:14px;"> <span style="width: 50px;margin-right:14px;">
<span class="fal fa-globe text-lighter fa-lg"></span> <span class="fal fa-globe text-lighter fa-lg"></span>
</span> </span>
@ -90,7 +90,7 @@
</span> </span>
Home Home
</a> </a>
<a class="dropdown-item lead" href="{{route('timeline.public')}}"> <a class="dropdown-item lead" href="/i/web/timeline/local">
<span style="width: 50px;margin-right:14px;"> <span style="width: 50px;margin-right:14px;">
<span class="fas fa-stream text-lighter fa-lg"></span> <span class="fas fa-stream text-lighter fa-lg"></span>
</span> </span>
@ -98,12 +98,13 @@
</a> </a>
@endif @endif
<div class="dropdown-divider"></div> <div class="dropdown-divider"></div>
<a class="dropdown-item lead" href="{{route('discover')}}"> <a class="dropdown-item lead" href="/i/web/discover">
<span style="width: 50px;margin-right:14px;"> <span style="width: 50px;margin-right:14px;">
<span class="fal fa-compass text-lighter fa-lg"></span> <span class="fal fa-compass text-lighter fa-lg"></span>
</span> </span>
{{__('navmenu.discover')}} {{__('navmenu.discover')}}
</a> </a>
@if(config_cache('instance.stories.enabled')) @if(config_cache('instance.stories.enabled'))
<a class="dropdown-item lead" href="/i/stories/new"> <a class="dropdown-item lead" href="/i/stories/new">
<span style="width: 50px;margin-right:14px;"> <span style="width: 50px;margin-right:14px;">
@ -119,14 +120,14 @@
</span> </span>
{{__('navmenu.myProfile')}} {{__('navmenu.myProfile')}}
</a> </a>
<a class="dropdown-item lead" href="{{route('settings')}}"> <a class="dropdown-item lead" href="/settings/home">
<span style="width: 50px;margin-right:14px;"> <span style="width: 50px;margin-right:14px;">
<span class="fal fa-cog text-lighter fa-lg"></span> <span class="fal fa-cog text-lighter fa-lg"></span>
</span> </span>
{{__('navmenu.settings')}} {{__('navmenu.settings')}}
</a> </a>
@if(Auth::user()->is_admin == true) @if(Auth::user()->is_admin == true)
<a class="dropdown-item lead" href="{{ route('admin.home') }}"> <a class="dropdown-item lead" href="/i/admin/dashboard">
<span style="width: 50px;margin-right:14px;"> <span style="width: 50px;margin-right:14px;">
<span class="fal fa-shield-alt text-lighter fa-lg"></span> <span class="fal fa-shield-alt text-lighter fa-lg"></span>
</span> </span>
@ -134,7 +135,7 @@
</a> </a>
@endif @endif
<div class="dropdown-divider"></div> <div class="dropdown-divider"></div>
<a class="dropdown-item lead" href="{{ route('logout') }}" <a class="dropdown-item lead" href="/logout"
onclick="event.preventDefault(); onclick="event.preventDefault();
document.getElementById('logout-form').submit();"> document.getElementById('logout-form').submit();">
<span style="width: 50px;margin-right:14px;" class="text-lighter"> <span style="width: 50px;margin-right:14px;" class="text-lighter">
@ -143,7 +144,7 @@
<span class="text-lighter">{{ __('navmenu.logout') }}</span> <span class="text-lighter">{{ __('navmenu.logout') }}</span>
</a> </a>
<form id="logout-form" action="{{ route('logout') }}" method="POST" style="display: none;"> <form id="logout-form" action="/logout" method="POST" style="display: none;">
@csrf @csrf
</form> </form>
</div> </div>

View file

@ -1,2 +1,3 @@
* *
!missing.png
!.gitignore !.gitignore

Binary file not shown.

After

Width:  |  Height:  |  Size: 81 B