mirror of
https://github.com/pixelfed/pixelfed.git
synced 2024-11-26 00:03:16 +00:00
commit
14ee32adf0
17 changed files with 253 additions and 99 deletions
|
@ -17,6 +17,11 @@
|
||||||
- Updated Timeline component, cascade relationship state change. ([f4bd5672](https://github.com/pixelfed/pixelfed/commit/f4bd5672))
|
- Updated Timeline component, cascade relationship state change. ([f4bd5672](https://github.com/pixelfed/pixelfed/commit/f4bd5672))
|
||||||
- Updated Activity component, only show context button for actionable activities. ([7886fd59](https://github.com/pixelfed/pixelfed/commit/7886fd59))
|
- Updated Activity component, only show context button for actionable activities. ([7886fd59](https://github.com/pixelfed/pixelfed/commit/7886fd59))
|
||||||
- Updated Autospam service, use silent classification for better user experience. ([f0d4c172](https://github.com/pixelfed/pixelfed/commit/f0d4c172))
|
- Updated Autospam service, use silent classification for better user experience. ([f0d4c172](https://github.com/pixelfed/pixelfed/commit/f0d4c172))
|
||||||
|
- Updated Profile component, improve error messages when block/mute limit reached. ([02237845](https://github.com/pixelfed/pixelfed/commit/02237845))
|
||||||
|
- Updated Activity component, fix missing types. ([5167c68d](https://github.com/pixelfed/pixelfed/commit/5167c68d))
|
||||||
|
- Updated Timeline component, apply block/mute filters client side for local and network timelines. ([be194b8a](https://github.com/pixelfed/pixelfed/commit/be194b8a))
|
||||||
|
- Updated public timeline api, use cached sorted set and client side block/mute filtering. ([37abcf38](https://github.com/pixelfed/pixelfed/commit/37abcf38))
|
||||||
|
- Updated public timeline api, add experimental cache. ([192553ff](https://github.com/pixelfed/pixelfed/commit/192553ff))
|
||||||
- ([](https://github.com/pixelfed/pixelfed/commit/))
|
- ([](https://github.com/pixelfed/pixelfed/commit/))
|
||||||
|
|
||||||
## [v0.11.1 (2021-09-07)](https://github.com/pixelfed/pixelfed/compare/v0.11.0...v0.11.1)
|
## [v0.11.1 (2021-09-07)](https://github.com/pixelfed/pixelfed/compare/v0.11.0...v0.11.1)
|
||||||
|
|
|
@ -26,6 +26,8 @@ use League\Fractal;
|
||||||
use League\Fractal\Serializer\ArraySerializer;
|
use League\Fractal\Serializer\ArraySerializer;
|
||||||
use League\Fractal\Pagination\IlluminatePaginatorAdapter;
|
use League\Fractal\Pagination\IlluminatePaginatorAdapter;
|
||||||
use App\Transformer\Api\Mastodon\v1\AccountTransformer;
|
use App\Transformer\Api\Mastodon\v1\AccountTransformer;
|
||||||
|
use App\Services\AccountService;
|
||||||
|
use App\Services\UserFilterService;
|
||||||
|
|
||||||
class AccountController extends Controller
|
class AccountController extends Controller
|
||||||
{
|
{
|
||||||
|
@ -34,6 +36,8 @@ class AccountController extends Controller
|
||||||
'user.block',
|
'user.block',
|
||||||
];
|
];
|
||||||
|
|
||||||
|
const FILTER_LIMIT = 'You cannot block or mute more than 100 accounts';
|
||||||
|
|
||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
$this->middleware('auth');
|
$this->middleware('auth');
|
||||||
|
@ -140,6 +144,12 @@ class AccountController extends Controller
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$user = Auth::user()->profile;
|
$user = Auth::user()->profile;
|
||||||
|
$count = UserFilterService::muteCount($user->id);
|
||||||
|
abort_if($count >= 100, 422, self::FILTER_LIMIT);
|
||||||
|
if($count == 0) {
|
||||||
|
$filterCount = UserFilter::whereUserId($user->id)->count();
|
||||||
|
abort_if($filterCount >= 100, 422, self::FILTER_LIMIT);
|
||||||
|
}
|
||||||
$type = $request->input('type');
|
$type = $request->input('type');
|
||||||
$item = $request->input('item');
|
$item = $request->input('item');
|
||||||
$action = $type . '.mute';
|
$action = $type . '.mute';
|
||||||
|
@ -237,6 +247,12 @@ class AccountController extends Controller
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$user = Auth::user()->profile;
|
$user = Auth::user()->profile;
|
||||||
|
$count = UserFilterService::blockCount($user->id);
|
||||||
|
abort_if($count >= 100, 422, self::FILTER_LIMIT);
|
||||||
|
if($count == 0) {
|
||||||
|
$filterCount = UserFilter::whereUserId($user->id)->count();
|
||||||
|
abort_if($filterCount >= 100, 422, self::FILTER_LIMIT);
|
||||||
|
}
|
||||||
$type = $request->input('type');
|
$type = $request->input('type');
|
||||||
$item = $request->input('item');
|
$item = $request->input('item');
|
||||||
$action = $type.'.block';
|
$action = $type.'.block';
|
||||||
|
@ -552,5 +568,21 @@ class AccountController extends Controller
|
||||||
$prev = $page > 1 ? $page - 1 : 1;
|
$prev = $page > 1 ? $page - 1 : 1;
|
||||||
$links = '<'.$url.'?page='.$next.'&limit='.$limit.'>; rel="next", <'.$url.'?page='.$prev.'&limit='.$limit.'>; rel="prev"';
|
$links = '<'.$url.'?page='.$next.'&limit='.$limit.'>; rel="next", <'.$url.'?page='.$prev.'&limit='.$limit.'>; rel="prev"';
|
||||||
return response()->json($res, 200, ['Link' => $links]);
|
return response()->json($res, 200, ['Link' => $links]);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public function accountBlocksV2(Request $request)
|
||||||
|
{
|
||||||
|
return response()->json(UserFilterService::blocks($request->user()->profile_id), 200, [], JSON_UNESCAPED_SLASHES);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function accountMutesV2(Request $request)
|
||||||
|
{
|
||||||
|
return response()->json(UserFilterService::mutes($request->user()->profile_id), 200, [], JSON_UNESCAPED_SLASHES);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function accountFiltersV2(Request $request)
|
||||||
|
{
|
||||||
|
return response()->json(UserFilterService::filters($request->user()->profile_id), 200, [], JSON_UNESCAPED_SLASHES);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -58,7 +58,8 @@ use App\Services\{
|
||||||
RelationshipService,
|
RelationshipService,
|
||||||
SearchApiV2Service,
|
SearchApiV2Service,
|
||||||
StatusService,
|
StatusService,
|
||||||
MediaBlocklistService
|
MediaBlocklistService,
|
||||||
|
UserFilterService
|
||||||
};
|
};
|
||||||
use App\Util\Lexer\Autolink;
|
use App\Util\Lexer\Autolink;
|
||||||
|
|
||||||
|
@ -563,8 +564,11 @@ class ApiV1Controller extends Controller
|
||||||
'id.*' => 'required|integer|min:1|max:' . PHP_INT_MAX
|
'id.*' => 'required|integer|min:1|max:' . PHP_INT_MAX
|
||||||
]);
|
]);
|
||||||
$pid = $request->user()->profile_id ?? $request->user()->profile->id;
|
$pid = $request->user()->profile_id ?? $request->user()->profile->id;
|
||||||
$ids = collect($request->input('id'));
|
$res = collect($request->input('id'))
|
||||||
$res = $ids->map(function($id) use($pid) {
|
->filter(function($id) use($pid) {
|
||||||
|
return $id != $pid;
|
||||||
|
})
|
||||||
|
->map(function($id) use($pid) {
|
||||||
return RelationshipService::get($pid, $id);
|
return RelationshipService::get($pid, $id);
|
||||||
});
|
});
|
||||||
return response()->json($res);
|
return response()->json($res);
|
||||||
|
@ -1484,8 +1488,9 @@ class ApiV1Controller extends Controller
|
||||||
$max = $request->input('max_id');
|
$max = $request->input('max_id');
|
||||||
$limit = $request->input('limit') ?? 3;
|
$limit = $request->input('limit') ?? 3;
|
||||||
$user = $request->user();
|
$user = $request->user();
|
||||||
|
$filtered = $user ? UserFilterService::filters($user->profile_id) : [];
|
||||||
|
|
||||||
Cache::remember('api:v1:timelines:public:cache_check', 3600, function() {
|
Cache::remember('api:v1:timelines:public:cache_check', 10368000, function() {
|
||||||
if(PublicTimelineService::count() == 0) {
|
if(PublicTimelineService::count() == 0) {
|
||||||
PublicTimelineService::warmCache(true, 400);
|
PublicTimelineService::warmCache(true, 400);
|
||||||
}
|
}
|
||||||
|
@ -1504,9 +1509,13 @@ class ApiV1Controller 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['relationship'] = RelationshipService::get($user->profile_id, $status['account']['id']);
|
||||||
}
|
}
|
||||||
return $status;
|
return $status;
|
||||||
})
|
})
|
||||||
|
->filter(function($s) use($filtered) {
|
||||||
|
return in_array($s['account']['id'], $filtered) == false;
|
||||||
|
})
|
||||||
->toArray();
|
->toArray();
|
||||||
return response()->json($res);
|
return response()->json($res);
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,7 +56,7 @@ class LikeController extends Controller
|
||||||
}
|
}
|
||||||
|
|
||||||
Cache::forget('status:'.$status->id.':likedby:userid:'.$user->id);
|
Cache::forget('status:'.$status->id.':likedby:userid:'.$user->id);
|
||||||
StatusService::del($status->id);
|
StatusService::refresh($status->id);
|
||||||
|
|
||||||
if ($request->ajax()) {
|
if ($request->ajax()) {
|
||||||
$response = ['code' => 200, 'msg' => 'Like saved', 'count' => 0];
|
$response = ['code' => 200, 'msg' => 'Like saved', 'count' => 0];
|
||||||
|
|
|
@ -30,6 +30,7 @@ use App\Services\{
|
||||||
LikeService,
|
LikeService,
|
||||||
PublicTimelineService,
|
PublicTimelineService,
|
||||||
ProfileService,
|
ProfileService,
|
||||||
|
RelationshipService,
|
||||||
StatusService,
|
StatusService,
|
||||||
SnowflakeService,
|
SnowflakeService,
|
||||||
UserFilterService
|
UserFilterService
|
||||||
|
@ -38,7 +39,6 @@ use App\Jobs\StatusPipeline\NewStatusPipeline;
|
||||||
use League\Fractal\Serializer\ArraySerializer;
|
use League\Fractal\Serializer\ArraySerializer;
|
||||||
use League\Fractal\Pagination\IlluminatePaginatorAdapter;
|
use League\Fractal\Pagination\IlluminatePaginatorAdapter;
|
||||||
|
|
||||||
|
|
||||||
class PublicApiController extends Controller
|
class PublicApiController extends Controller
|
||||||
{
|
{
|
||||||
protected $fractal;
|
protected $fractal;
|
||||||
|
@ -287,9 +287,9 @@ class PublicApiController extends Controller
|
||||||
$max = $request->input('max_id');
|
$max = $request->input('max_id');
|
||||||
$limit = $request->input('limit') ?? 3;
|
$limit = $request->input('limit') ?? 3;
|
||||||
$user = $request->user();
|
$user = $request->user();
|
||||||
|
|
||||||
$filtered = $user ? UserFilterService::filters($user->profile_id) : [];
|
$filtered = $user ? UserFilterService::filters($user->profile_id) : [];
|
||||||
|
|
||||||
|
if(config('exp.cached_public_timeline') == false) {
|
||||||
if($min || $max) {
|
if($min || $max) {
|
||||||
$dir = $min ? '>' : '<';
|
$dir = $min ? '>' : '<';
|
||||||
$id = $min ?? $max;
|
$id = $min ?? $max;
|
||||||
|
@ -302,7 +302,6 @@ class PublicApiController extends Controller
|
||||||
)
|
)
|
||||||
->where('id', $dir, $id)
|
->where('id', $dir, $id)
|
||||||
->whereIn('type', ['photo', 'photo:album', 'video', 'video:album', 'photo:video:album'])
|
->whereIn('type', ['photo', 'photo:album', 'video', 'video:album', 'photo:video:album'])
|
||||||
->whereNotIn('profile_id', $filtered)
|
|
||||||
->whereLocal(true)
|
->whereLocal(true)
|
||||||
->whereScope('public')
|
->whereScope('public')
|
||||||
->orderBy('id', 'desc')
|
->orderBy('id', 'desc')
|
||||||
|
@ -312,6 +311,9 @@ class PublicApiController extends Controller
|
||||||
$status = StatusService::getFull($s->id, $user->profile_id);
|
$status = StatusService::getFull($s->id, $user->profile_id);
|
||||||
$status['favourited'] = (bool) LikeService::liked($user->profile_id, $s->id);
|
$status['favourited'] = (bool) LikeService::liked($user->profile_id, $s->id);
|
||||||
return $status;
|
return $status;
|
||||||
|
})
|
||||||
|
->filter(function($s) use($filtered) {
|
||||||
|
return in_array($s['account']['id'], $filtered) == false;
|
||||||
});
|
});
|
||||||
$res = $timeline->toArray();
|
$res = $timeline->toArray();
|
||||||
} else {
|
} else {
|
||||||
|
@ -336,7 +338,6 @@ class PublicApiController extends Controller
|
||||||
'updated_at'
|
'updated_at'
|
||||||
)
|
)
|
||||||
->whereIn('type', ['photo', 'photo:album', 'video', 'video:album', 'photo:video:album'])
|
->whereIn('type', ['photo', 'photo:album', 'video', 'video:album', 'photo:video:album'])
|
||||||
->whereNotIn('profile_id', $filtered)
|
|
||||||
->with('profile', 'hashtags', 'mentions')
|
->with('profile', 'hashtags', 'mentions')
|
||||||
->whereLocal(true)
|
->whereLocal(true)
|
||||||
->whereScope('public')
|
->whereScope('public')
|
||||||
|
@ -347,10 +348,42 @@ class PublicApiController extends Controller
|
||||||
$status = StatusService::getFull($s->id, $user->profile_id);
|
$status = StatusService::getFull($s->id, $user->profile_id);
|
||||||
$status['favourited'] = (bool) LikeService::liked($user->profile_id, $s->id);
|
$status['favourited'] = (bool) LikeService::liked($user->profile_id, $s->id);
|
||||||
return $status;
|
return $status;
|
||||||
|
})
|
||||||
|
->filter(function($s) use($filtered) {
|
||||||
|
return in_array($s['account']['id'], $filtered) == false;
|
||||||
});
|
});
|
||||||
|
|
||||||
$res = $timeline->toArray();
|
$res = $timeline->toArray();
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
Cache::remember('api:v1:timelines:public:cache_check', 10368000, function() {
|
||||||
|
if(PublicTimelineService::count() == 0) {
|
||||||
|
PublicTimelineService::warmCache(true, 400);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if ($max) {
|
||||||
|
$feed = PublicTimelineService::getRankedMaxId($max, $limit);
|
||||||
|
} else if ($min) {
|
||||||
|
$feed = PublicTimelineService::getRankedMinId($min, $limit);
|
||||||
|
} else {
|
||||||
|
$feed = PublicTimelineService::get(0, $limit);
|
||||||
|
}
|
||||||
|
|
||||||
|
$res = collect($feed)
|
||||||
|
->map(function($k) use($user) {
|
||||||
|
$status = StatusService::get($k);
|
||||||
|
if($user) {
|
||||||
|
$status['favourited'] = (bool) LikeService::liked($user->profile_id, $k);
|
||||||
|
$status['relationship'] = RelationshipService::get($user->profile_id, $status['account']['id']);
|
||||||
|
}
|
||||||
|
return $status;
|
||||||
|
})
|
||||||
|
->filter(function($s) use($filtered) {
|
||||||
|
return in_array($s['account']['id'], $filtered) == false;
|
||||||
|
})
|
||||||
|
->toArray();
|
||||||
|
}
|
||||||
|
|
||||||
return response()->json($res);
|
return response()->json($res);
|
||||||
}
|
}
|
||||||
|
@ -580,17 +613,20 @@ class PublicApiController extends Controller
|
||||||
return response()->json([]);
|
return response()->json([]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$pid = $request->user()->profile_id;
|
||||||
|
|
||||||
$this->validate($request, [
|
$this->validate($request, [
|
||||||
'id' => 'required|array|min:1|max:20',
|
'id' => 'required|array|min:1|max:20',
|
||||||
'id.*' => 'required|integer'
|
'id.*' => 'required|integer'
|
||||||
]);
|
]);
|
||||||
$ids = collect($request->input('id'));
|
$ids = collect($request->input('id'));
|
||||||
$filtered = $ids->filter(function($v) {
|
$res = $ids->filter(function($v) use($pid) {
|
||||||
return $v != Auth::user()->profile->id;
|
return $v != $pid;
|
||||||
|
})
|
||||||
|
->map(function($id) use($pid) {
|
||||||
|
return RelationshipService::get($pid, $id);
|
||||||
});
|
});
|
||||||
$relations = Profile::whereNull('status')->findOrFail($filtered->all());
|
|
||||||
$fractal = new Fractal\Resource\Collection($relations, new RelationshipTransformer());
|
|
||||||
$res = $this->fractal->createData($fractal)->toArray();
|
|
||||||
return response()->json($res);
|
return response()->json($res);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -741,5 +777,4 @@ class PublicApiController extends Controller
|
||||||
|
|
||||||
return response()->json($res);
|
return response()->json($res);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -59,7 +59,7 @@ class LikePipeline implements ShouldQueue
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
StatusService::del($status->id);
|
StatusService::refresh($status->id);
|
||||||
|
|
||||||
if($status->url && $actor->domain == null) {
|
if($status->url && $actor->domain == null) {
|
||||||
return $this->remoteLikeDeliver();
|
return $this->remoteLikeDeliver();
|
||||||
|
|
|
@ -63,7 +63,7 @@ class UnlikePipeline implements ShouldQueue
|
||||||
$status->likes_count = $count - 1;
|
$status->likes_count = $count - 1;
|
||||||
$status->save();
|
$status->save();
|
||||||
|
|
||||||
StatusService::del($status->id);
|
StatusService::refresh($status->id);
|
||||||
|
|
||||||
if($actor->id !== $status->profile_id && $status->url && $actor->domain == null) {
|
if($actor->id !== $status->profile_id && $status->url && $actor->domain == null) {
|
||||||
$this->remoteLikeDeliver();
|
$this->remoteLikeDeliver();
|
||||||
|
|
|
@ -8,6 +8,8 @@ use App\Status;
|
||||||
use App\Transformer\Api\AccountTransformer;
|
use App\Transformer\Api\AccountTransformer;
|
||||||
use League\Fractal;
|
use League\Fractal;
|
||||||
use League\Fractal\Serializer\ArraySerializer;
|
use League\Fractal\Serializer\ArraySerializer;
|
||||||
|
use Illuminate\Support\Facades\DB;
|
||||||
|
use Illuminate\Support\Str;
|
||||||
|
|
||||||
class AccountService
|
class AccountService
|
||||||
{
|
{
|
||||||
|
@ -62,4 +64,22 @@ class AccountService
|
||||||
Cache::put($key, 1, 900);
|
Cache::put($key, 1, 900);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static function usernameToId($username)
|
||||||
|
{
|
||||||
|
$key = self::CACHE_KEY . 'u2id:' . hash('sha256', $username);
|
||||||
|
return Cache::remember($key, 900, function() use($username) {
|
||||||
|
$s = Str::of($username);
|
||||||
|
if($s->contains('@') && !$s->startsWith('@')) {
|
||||||
|
$username = "@{$username}";
|
||||||
|
}
|
||||||
|
$profile = DB::table('profiles')
|
||||||
|
->whereUsername($username)
|
||||||
|
->first();
|
||||||
|
if(!$profile) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return (string) $profile->id;
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,4 +62,12 @@ class StatusService {
|
||||||
Cache::forget(self::key($id, false));
|
Cache::forget(self::key($id, false));
|
||||||
return Cache::forget(self::key($id));
|
return Cache::forget(self::key($id));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static function refresh($id)
|
||||||
|
{
|
||||||
|
Cache::forget(self::key($id, false));
|
||||||
|
Cache::forget(self::key($id, true));
|
||||||
|
self::get($id, false);
|
||||||
|
self::get($id, true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -98,4 +98,14 @@ class UserFilterService {
|
||||||
}
|
}
|
||||||
return $exists;
|
return $exists;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static function blockCount(int $profile_id)
|
||||||
|
{
|
||||||
|
return Redis::zcard(self::USER_BLOCKS_KEY . $profile_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function muteCount(int $profile_id)
|
||||||
|
{
|
||||||
|
return Redis::zcard(self::USER_MUTES_KEY . $profile_id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,5 +6,6 @@ return [
|
||||||
'rec' => false,
|
'rec' => false,
|
||||||
'loops' => false,
|
'loops' => false,
|
||||||
'top' => env('EXP_TOP', false),
|
'top' => env('EXP_TOP', false),
|
||||||
'polls' => env('EXP_POLLS', false)
|
'polls' => env('EXP_POLLS', false),
|
||||||
|
'cached_public_timeline' => env('EXP_CPT', false),
|
||||||
];
|
];
|
||||||
|
|
|
@ -76,6 +76,19 @@
|
||||||
<a :href="getProfileUrl(n.account)" class="font-weight-bold text-dark word-break" :title="n.account.username">{{n.account.local == false ? '@':''}}{{truncate(n.account.username)}}</a> tagged you in a <a class="font-weight-bold" v-bind:href="n.tagged.post_url">post</a>.
|
<a :href="getProfileUrl(n.account)" class="font-weight-bold text-dark word-break" :title="n.account.username">{{n.account.local == false ? '@':''}}{{truncate(n.account.username)}}</a> tagged you in a <a class="font-weight-bold" v-bind:href="n.tagged.post_url">post</a>.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div v-else-if="n.type == 'direct'">
|
||||||
|
<p class="my-0">
|
||||||
|
<a :href="getProfileUrl(n.account)" class="font-weight-bold text-dark word-break" :title="n.account.username">{{n.account.local == false ? '@':''}}{{truncate(n.account.username)}}</a> sent a <a class="font-weight-bold" v-bind:href="'/account/direct/t/'+n.account.id">dm</a>.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div v-else-if="n.type == 'direct'">
|
||||||
|
<p class="my-0">
|
||||||
|
<a :href="getProfileUrl(n.account)" class="font-weight-bold text-dark word-break" :title="n.account.username">{{n.account.local == false ? '@':''}}{{truncate(n.account.username)}}</a> sent a <a class="font-weight-bold" v-bind:href="'/account/direct/t/'+n.account.id">dm</a>.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="align-items-center">
|
<div class="align-items-center">
|
||||||
<span class="small text-muted" data-toggle="tooltip" data-placement="bottom" :title="n.created_at">{{timeAgo(n.created_at)}}</span>
|
<span class="small text-muted" data-toggle="tooltip" data-placement="bottom" :title="n.created_at">{{timeAgo(n.created_at)}}</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1078,7 +1078,11 @@
|
||||||
this.$refs.visitorContextMenu.hide();
|
this.$refs.visitorContextMenu.hide();
|
||||||
swal('Success', 'You have successfully muted ' + this.profile.acct, 'success');
|
swal('Success', 'You have successfully muted ' + this.profile.acct, 'success');
|
||||||
}).catch(err => {
|
}).catch(err => {
|
||||||
|
if(err.response.status == 422) {
|
||||||
|
swal('Error', err.response.data.error, 'error');
|
||||||
|
} else {
|
||||||
swal('Error', 'Something went wrong. Please try again later.', 'error');
|
swal('Error', 'Something went wrong. Please try again later.', 'error');
|
||||||
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -1113,7 +1117,11 @@
|
||||||
this.$refs.visitorContextMenu.hide();
|
this.$refs.visitorContextMenu.hide();
|
||||||
swal('Success', 'You have successfully blocked ' + this.profile.acct, 'success');
|
swal('Success', 'You have successfully blocked ' + this.profile.acct, 'success');
|
||||||
}).catch(err => {
|
}).catch(err => {
|
||||||
|
if(err.response.status == 422) {
|
||||||
|
swal('Error', err.response.data.error, 'error');
|
||||||
|
} else {
|
||||||
swal('Error', 'Something went wrong. Please try again later.', 'error');
|
swal('Error', 'Something went wrong. Please try again later.', 'error');
|
||||||
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -508,7 +508,8 @@
|
||||||
recentFeedMin: null,
|
recentFeedMin: null,
|
||||||
recentFeedMax: null,
|
recentFeedMax: null,
|
||||||
reactionBar: true,
|
reactionBar: true,
|
||||||
emptyFeed: false
|
emptyFeed: false,
|
||||||
|
filters: []
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -567,8 +568,17 @@
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(this.scope != 'home') {
|
||||||
|
axios.get('/api/pixelfed/v2/filters')
|
||||||
|
.then(res => {
|
||||||
|
this.filters = res.data;
|
||||||
this.fetchTimelineApi();
|
this.fetchTimelineApi();
|
||||||
});
|
});
|
||||||
|
} else {
|
||||||
|
this.fetchTimelineApi();
|
||||||
|
}
|
||||||
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
updated() {
|
updated() {
|
||||||
|
@ -629,6 +639,12 @@
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(this.filters.length) {
|
||||||
|
data = data.filter(d => {
|
||||||
|
return this.filters.includes(d.account.id) == false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
this.feed.push(...data);
|
this.feed.push(...data);
|
||||||
let ids = data.map(status => status.id);
|
let ids = data.map(status => status.id);
|
||||||
this.ids = ids;
|
this.ids = ids;
|
||||||
|
|
|
@ -401,7 +401,7 @@
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(status.account.id === this.profile.id) {
|
if(status.account.id == this.profile.id) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -65,7 +65,7 @@
|
||||||
|
|
||||||
<div class="dropdown-menu dropdown-menu-right px-0 shadow" aria-labelledby="navbarDropdown" style="min-width: 220px;">
|
<div class="dropdown-menu dropdown-menu-right px-0 shadow" aria-labelledby="navbarDropdown" style="min-width: 220px;">
|
||||||
@if(config('federation.network_timeline'))
|
@if(config('federation.network_timeline'))
|
||||||
<a class="dropdown-item lead" href="{{route('timeline.public')}}">
|
<a class="dropdown-item lead" href="/">
|
||||||
<span style="width: 50px;margin-right:14px;">
|
<span style="width: 50px;margin-right:14px;">
|
||||||
<span class="fal fa-home text-lighter fa-lg"></span>
|
<span class="fal fa-home text-lighter fa-lg"></span>
|
||||||
</span>
|
</span>
|
||||||
|
@ -104,12 +104,6 @@
|
||||||
</span>
|
</span>
|
||||||
{{__('navmenu.discover')}}
|
{{__('navmenu.discover')}}
|
||||||
</a>
|
</a>
|
||||||
{{-- <a class="dropdown-item lead" href="/groups">
|
|
||||||
<span style="width: 50px;margin-right:14px;">
|
|
||||||
<span class="fal fa-user-friends text-lighter"></span>
|
|
||||||
</span>
|
|
||||||
Groups
|
|
||||||
</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;">
|
||||||
|
|
|
@ -202,6 +202,9 @@ Route::domain(config('pixelfed.domain.app'))->middleware(['validemail', 'twofact
|
||||||
Route::post('status/{id}/archive', 'ApiController@archive');
|
Route::post('status/{id}/archive', 'ApiController@archive');
|
||||||
Route::post('status/{id}/unarchive', 'ApiController@unarchive');
|
Route::post('status/{id}/unarchive', 'ApiController@unarchive');
|
||||||
Route::get('statuses/archives', 'ApiController@archivedPosts');
|
Route::get('statuses/archives', 'ApiController@archivedPosts');
|
||||||
|
Route::get('mutes', 'AccountController@accountMutesV2');
|
||||||
|
Route::get('blocks', 'AccountController@accountBlocksV2');
|
||||||
|
Route::get('filters', 'AccountController@accountFiltersV2');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue