mirror of
https://github.com/pixelfed/pixelfed.git
synced 2024-11-22 14:31:26 +00:00
commit
8757476aff
28 changed files with 195 additions and 66 deletions
|
@ -115,7 +115,7 @@ PF_COSTAR_ENABLED=false
|
|||
MEDIA_EXIF_DATABASE=false
|
||||
|
||||
## Logging
|
||||
LOG_CHANNEL=stack
|
||||
LOG_CHANNEL=stderr
|
||||
|
||||
## Image
|
||||
IMAGE_DRIVER=imagick
|
||||
|
|
14
CHANGELOG.md
14
CHANGELOG.md
|
@ -6,7 +6,19 @@
|
|||
### Updated
|
||||
- Updated AdminController, fix variable name in updateSpam method. ([6edaf940](https://github.com/pixelfed/pixelfed/commit/6edaf940))
|
||||
- Updated RemotAvatarFetch, only dispatch jobs if cloud storage is enabled. ([4f40f6f5](https://github.com/pixelfed/pixelfed/commit/4f40f6f5))
|
||||
|
||||
- Updated StatusService, add ttl of 7 days. ([6e44ae0b](https://github.com/pixelfed/pixelfed/commit/6e44ae0b))
|
||||
- Updated StatusHashtagService, use StatusService for statuses. ([0355b567](https://github.com/pixelfed/pixelfed/commit/0355b567))
|
||||
- Updated StatusHashtagService, remove deprecated methods. ([aa4c718d](https://github.com/pixelfed/pixelfed/commit/aa4c718d))
|
||||
- Updated ApiV1Controller, add StatusService del calls to update likes_count, reblogs_count and reply_count. ([05b9445c](https://github.com/pixelfed/pixelfed/commit/05b9445c))
|
||||
- Updated Like, Status and Comment controllers to add StatusService del() method to update counts. ([eab4370c](https://github.com/pixelfed/pixelfed/commit/eab4370c))
|
||||
- Updated ComposeController, use placeholder image for video media. Fixes #2595. ([789ed4b4](https://github.com/pixelfed/pixelfed/commit/789ed4b4))
|
||||
- Updated DiscoverController, change api schema. ([2eea0409](https://github.com/pixelfed/pixelfed/commit/2eea0409))
|
||||
- Updated StatusDelete pipeline, call StatusService::del() to remove status from cache. ([3f772ff8](https://github.com/pixelfed/pixelfed/commit/3f772ff8))
|
||||
- Updated StatusHashtagTransformer, add blurhash attribute. ([899bbeba](https://github.com/pixelfed/pixelfed/commit/899bbeba))
|
||||
- Updated status square previews, add blurhash and improved content warnings. ([39e389dd](https://github.com/pixelfed/pixelfed/commit/39e389dd))
|
||||
- Updated Blurhash util, add default hash for invalid media. ([38a37c15](https://github.com/pixelfed/pixelfed/commit/38a37c15))
|
||||
- Updated VideoThumbnail job, generate blurhash for videos. ([896452c7](https://github.com/pixelfed/pixelfed/commit/896452c7))
|
||||
- Updated MediaTransformers, add default blurhash attribute. ([3f14a4c4](https://github.com/pixelfed/pixelfed/commit/3f14a4c4))
|
||||
|
||||
## [v0.10.10 (2021-01-28)](https://github.com/pixelfed/pixelfed/compare/v0.10.9...v0.10.10)
|
||||
### Added
|
||||
|
|
|
@ -50,6 +50,7 @@ use App\Services\{
|
|||
NotificationService,
|
||||
MediaPathService,
|
||||
SearchApiV2Service,
|
||||
StatusService,
|
||||
MediaBlocklistService
|
||||
};
|
||||
|
||||
|
@ -856,6 +857,8 @@ class ApiV1Controller extends Controller
|
|||
$status->save();
|
||||
}
|
||||
|
||||
StatusService::del($status->id);
|
||||
|
||||
$resource = new Fractal\Resource\Item($status, new StatusTransformer());
|
||||
$res = $this->fractal->createData($resource)->toArray();
|
||||
return response()->json($res);
|
||||
|
@ -1766,6 +1769,7 @@ class ApiV1Controller extends Controller
|
|||
$status->in_reply_to_id = $parent->id;
|
||||
$status->in_reply_to_profile_id = $parent->profile_id;
|
||||
$status->save();
|
||||
StatusService::del($parent->id);
|
||||
} else if($ids) {
|
||||
if(Media::whereUserId($user->id)
|
||||
->whereNull('status_id')
|
||||
|
@ -1883,6 +1887,7 @@ class ApiV1Controller extends Controller
|
|||
SharePipeline::dispatch($share);
|
||||
}
|
||||
|
||||
StatusService::del($status->id);
|
||||
$resource = new Fractal\Resource\Item($status, new StatusTransformer());
|
||||
$res = $this->fractal->createData($resource)->toArray();
|
||||
return response()->json($res);
|
||||
|
@ -1916,6 +1921,7 @@ class ApiV1Controller extends Controller
|
|||
$status->reblogs_count = $status->shares()->count();
|
||||
$status->save();
|
||||
|
||||
StatusService::del($status->id);
|
||||
$resource = new Fractal\Resource\Item($status, new StatusTransformer());
|
||||
$res = $this->fractal->createData($resource)->toArray();
|
||||
return response()->json($res);
|
||||
|
|
|
@ -18,6 +18,7 @@ use League\Fractal;
|
|||
use App\Transformer\Api\StatusTransformer;
|
||||
use League\Fractal\Serializer\ArraySerializer;
|
||||
use League\Fractal\Pagination\IlluminatePaginatorAdapter;
|
||||
use App\Services\StatusService;
|
||||
|
||||
class CommentController extends Controller
|
||||
{
|
||||
|
@ -78,6 +79,7 @@ class CommentController extends Controller
|
|||
return $reply;
|
||||
});
|
||||
|
||||
StatusService::del($status->id);
|
||||
NewStatusPipeline::dispatch($reply, false);
|
||||
CommentPipeline::dispatch($status, $reply);
|
||||
|
||||
|
|
|
@ -39,6 +39,7 @@ use App\Services\NotificationService;
|
|||
use App\Services\MediaPathService;
|
||||
use App\Services\MediaBlocklistService;
|
||||
use App\Services\MediaTagService;
|
||||
use App\Services\ServiceService;
|
||||
use Illuminate\Support\Str;
|
||||
use App\Util\Lexer\Autolink;
|
||||
use App\Util\Lexer\Extractor;
|
||||
|
@ -117,10 +118,9 @@ class ComposeController extends Controller
|
|||
$media->version = 3;
|
||||
$media->save();
|
||||
|
||||
// $url = URL::temporarySignedRoute(
|
||||
// 'temp-media', now()->addHours(1), ['profileId' => $profile->id, 'mediaId' => $media->id, 'timestamp' => time()]
|
||||
// );
|
||||
|
||||
$preview_url = $media->url() . '?v=' . time();
|
||||
$url = $media->url() . '?v=' . time();
|
||||
|
||||
switch ($media->mime) {
|
||||
case 'image/jpeg':
|
||||
case 'image/png':
|
||||
|
@ -139,8 +139,8 @@ class ComposeController extends Controller
|
|||
|
||||
$resource = new Fractal\Resource\Item($media, new MediaTransformer());
|
||||
$res = $this->fractal->createData($resource)->toArray();
|
||||
$res['preview_url'] = $media->url() . '?v=' . time();
|
||||
$res['url'] = $media->url() . '?v=' . time();
|
||||
$res['preview_url'] = $preview_url;
|
||||
$res['url'] = $url;
|
||||
return response()->json($res);
|
||||
}
|
||||
|
||||
|
|
|
@ -129,10 +129,16 @@ class DiscoverController extends Controller
|
|||
$tag = $request->input('hashtag');
|
||||
|
||||
$hashtag = Hashtag::whereName($tag)->firstOrFail();
|
||||
$res['tags'] = StatusHashtagService::get($hashtag->id, $page, $end);
|
||||
if($page == 1) {
|
||||
$res['follows'] = HashtagFollow::whereUserId(Auth::id())->whereHashtagId($hashtag->id)->exists();
|
||||
$res['follows'] = HashtagFollow::whereUserId(Auth::id())
|
||||
->whereHashtagId($hashtag->id)
|
||||
->exists();
|
||||
}
|
||||
$res['hashtag'] = [
|
||||
'name' => $hashtag->name,
|
||||
'url' => $hashtag->url()
|
||||
];
|
||||
$res['tags'] = StatusHashtagService::get($hashtag->id, $page, $end);
|
||||
return $res;
|
||||
}
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@ use App\User;
|
|||
use Auth;
|
||||
use Cache;
|
||||
use Illuminate\Http\Request;
|
||||
use App\Services\StatusService;
|
||||
|
||||
class LikeController extends Controller
|
||||
{
|
||||
|
@ -58,6 +59,7 @@ class LikeController extends Controller
|
|||
}
|
||||
|
||||
Cache::forget('status:'.$status->id.':likedby:userid:'.$user->id);
|
||||
StatusService::del($status->id);
|
||||
|
||||
if ($request->ajax()) {
|
||||
$response = ['code' => 200, 'msg' => 'Like saved', 'count' => $count];
|
||||
|
|
|
@ -20,6 +20,7 @@ use League\Fractal;
|
|||
use App\Util\Media\Filter;
|
||||
use Illuminate\Support\Str;
|
||||
use App\Services\HashidService;
|
||||
use App\Services\StatusService;
|
||||
|
||||
class StatusController extends Controller
|
||||
{
|
||||
|
@ -211,6 +212,7 @@ class StatusController extends Controller
|
|||
|
||||
Cache::forget('_api:statuses:recent_9:' . $status->profile_id);
|
||||
Cache::forget('profile:status_count:' . $status->profile_id);
|
||||
StatusService::del($status->id);
|
||||
if ($status->profile_id == $user->profile->id || $user->is_admin == true) {
|
||||
Cache::forget('profile:status_count:'.$status->profile_id);
|
||||
StatusDelete::dispatch($status);
|
||||
|
@ -266,7 +268,8 @@ class StatusController extends Controller
|
|||
}
|
||||
|
||||
Cache::forget('status:'.$status->id.':sharedby:userid:'.$user->id);
|
||||
|
||||
StatusService::del($status->id);
|
||||
|
||||
if ($request->ajax()) {
|
||||
$response = ['code' => 200, 'msg' => 'Share saved', 'count' => $count];
|
||||
} else {
|
||||
|
|
|
@ -14,6 +14,7 @@ use App\Util\ActivityPub\Helpers;
|
|||
use League\Fractal;
|
||||
use League\Fractal\Serializer\ArraySerializer;
|
||||
use App\Transformer\ActivityPub\Verb\Like as LikeTransformer;
|
||||
use App\Services\StatusService;
|
||||
|
||||
class LikePipeline implements ShouldQueue
|
||||
{
|
||||
|
@ -58,6 +59,8 @@ class LikePipeline implements ShouldQueue
|
|||
return;
|
||||
}
|
||||
|
||||
StatusService::del($status->id);
|
||||
|
||||
if($status->url && $actor->domain == null) {
|
||||
return $this->remoteLikeDeliver();
|
||||
}
|
||||
|
|
|
@ -25,6 +25,7 @@ use GuzzleHttp\Pool;
|
|||
use GuzzleHttp\Client;
|
||||
use GuzzleHttp\Promise;
|
||||
use App\Util\ActivityPub\HttpSignature;
|
||||
use App\Services\StatusService;
|
||||
|
||||
class StatusDelete implements ShouldQueue
|
||||
{
|
||||
|
@ -59,6 +60,7 @@ class StatusDelete implements ShouldQueue
|
|||
$status = $this->status;
|
||||
$profile = $this->status->profile;
|
||||
|
||||
StatusService::del($status->id);
|
||||
$count = $profile->statuses()
|
||||
->getQuery()
|
||||
->whereIn('type', ['photo', 'photo:album', 'video', 'video:album', 'photo:video:album'])
|
||||
|
|
|
@ -13,6 +13,7 @@ use FFMpeg;
|
|||
use Storage;
|
||||
use App\Media;
|
||||
use App\Jobs\MediaPipeline\MediaStoragePipeline;
|
||||
use App\Util\Media\Blurhash;
|
||||
|
||||
class VideoThumbnail implements ShouldQueue
|
||||
{
|
||||
|
@ -59,6 +60,12 @@ class VideoThumbnail implements ShouldQueue
|
|||
$media->thumbnail_path = $save;
|
||||
$media->save();
|
||||
|
||||
$blurhash = Blurhash::generate($media);
|
||||
if($blurhash) {
|
||||
$media->blurhash = $blurhash;
|
||||
$media->save();
|
||||
}
|
||||
|
||||
} catch (Exception $e) {
|
||||
|
||||
}
|
||||
|
|
|
@ -16,6 +16,10 @@ class StatusHashtagService {
|
|||
|
||||
public static function get($id, $page = 1, $stop = 9)
|
||||
{
|
||||
if($page > 20) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return StatusHashtag::whereHashtagId($id)
|
||||
->whereStatusVisibility('public')
|
||||
->whereHas('media')
|
||||
|
@ -47,12 +51,12 @@ class StatusHashtagService {
|
|||
|
||||
public static function set($key, $val)
|
||||
{
|
||||
return Redis::zadd(self::CACHE_KEY . $key, $val, $val);
|
||||
return 1;
|
||||
}
|
||||
|
||||
public static function del($key)
|
||||
{
|
||||
return Redis::zrem(self::CACHE_KEY . $key, $key);
|
||||
return 1;
|
||||
}
|
||||
|
||||
public static function count($id)
|
||||
|
@ -66,16 +70,6 @@ class StatusHashtagService {
|
|||
|
||||
public static function getStatus($statusId, $hashtagId)
|
||||
{
|
||||
return Cache::remember('pf:services:status-hashtag:post:'.$statusId.':hashtag:'.$hashtagId, now()->addMonths(3), function() use($statusId, $hashtagId) {
|
||||
$statusHashtag = StatusHashtag::with('profile', 'status', 'hashtag')
|
||||
->whereStatusVisibility('public')
|
||||
->whereStatusId($statusId)
|
||||
->whereHashtagId($hashtagId)
|
||||
->first();
|
||||
$fractal = new Fractal\Manager();
|
||||
$fractal->setSerializer(new ArraySerializer());
|
||||
$resource = new Fractal\Resource\Item($statusHashtag, new StatusHashtagTransformer());
|
||||
return $fractal->createData($resource)->toArray();
|
||||
});
|
||||
return ['status' => StatusService::get($statusId)];
|
||||
}
|
||||
}
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
namespace App\Services;
|
||||
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
use Illuminate\Support\Facades\Redis;
|
||||
use App\Status;
|
||||
//use App\Transformer\Api\v3\StatusTransformer;
|
||||
|
@ -15,34 +16,27 @@ class StatusService {
|
|||
|
||||
const CACHE_KEY = 'pf:services:status:';
|
||||
|
||||
public static function key($id)
|
||||
{
|
||||
return self::CACHE_KEY . $id;
|
||||
}
|
||||
|
||||
public static function get($id)
|
||||
{
|
||||
return json_decode(Redis::get(self::CACHE_KEY . $id) ?? self::coldGet($id), true);
|
||||
return Cache::remember(self::key($id), now()->addDays(7), function() use($id) {
|
||||
$status = Status::whereScope('public')->find($id);
|
||||
if(!$status) {
|
||||
return null;
|
||||
}
|
||||
$fractal = new Fractal\Manager();
|
||||
$fractal->setSerializer(new ArraySerializer());
|
||||
$resource = new Fractal\Resource\Item($status, new StatusStatelessTransformer());
|
||||
return $fractal->createData($resource)->toArray();
|
||||
});
|
||||
}
|
||||
|
||||
public static function coldGet($id)
|
||||
public static function del($id)
|
||||
{
|
||||
$status = Status::whereScope('public')->findOrFail($id);
|
||||
$fractal = new Fractal\Manager();
|
||||
$fractal->setSerializer(new ArraySerializer());
|
||||
$resource = new Fractal\Resource\Item($status, new StatusStatelessTransformer());
|
||||
$res = $fractal->createData($resource)->toJson();
|
||||
self::set($id, $res);
|
||||
return $res;
|
||||
}
|
||||
|
||||
public static function set($key, $val)
|
||||
{
|
||||
return Redis::set(self::CACHE_KEY . $key, $val);
|
||||
}
|
||||
|
||||
public static function del($key)
|
||||
{
|
||||
return Redis::del(self::CACHE_KEY . $key);
|
||||
}
|
||||
|
||||
public static function rem($key)
|
||||
{
|
||||
return self::del($key);
|
||||
return Cache::forget(self::key($id));
|
||||
}
|
||||
}
|
|
@ -18,7 +18,7 @@ class MediaTransformer extends Fractal\TransformerAbstract
|
|||
'text_url' => null,
|
||||
'meta' => null,
|
||||
'description' => $media->caption,
|
||||
'blurhash' => $media->blurhash
|
||||
'blurhash' => $media->blurhash ?? 'U4Rfzst8?bt7ogayj[j[~pfQ9Goe%Mj[WBay'
|
||||
];
|
||||
|
||||
if($media->width && $media->height) {
|
||||
|
|
|
@ -24,7 +24,7 @@ class MediaTransformer extends Fractal\TransformerAbstract
|
|||
'filter_name' => $media->filter_name,
|
||||
'filter_class' => $media->version == 1 ? $media->filter_class : null,
|
||||
'mime' => $media->mime,
|
||||
'blurhash' => $media->blurhash
|
||||
'blurhash' => $media->blurhash ?? 'U4Rfzst8?bt7ogayj[j[~pfQ9Goe%Mj[WBay'
|
||||
];
|
||||
|
||||
if($media->width && $media->height) {
|
||||
|
|
|
@ -20,6 +20,7 @@ class StatusHashtagTransformer extends Fractal\TransformerAbstract
|
|||
'url' => $status->url(),
|
||||
'thumb' => $status->thumb(true),
|
||||
'filter' => $status->firstMedia()->filter_class,
|
||||
'blurhash' => $status->firstMedia()->blurhash,
|
||||
'sensitive' => (bool) $status->is_nsfw,
|
||||
'like_count' => $status->likes_count,
|
||||
'share_count' => $status->reblogs_count,
|
||||
|
|
|
@ -20,6 +20,7 @@ class StatusStatelessTransformer extends Fractal\TransformerAbstract
|
|||
$taggedPeople = MediaTagService::get($status->id);
|
||||
|
||||
return [
|
||||
'_v' => 1,
|
||||
'id' => (string) $status->id,
|
||||
'shortcode' => HashidService::encode($status->id),
|
||||
'uri' => $status->url(),
|
||||
|
|
|
@ -22,6 +22,7 @@ class StatusTransformer extends Fractal\TransformerAbstract
|
|||
$taggedPeople = MediaTagService::get($status->id);
|
||||
|
||||
return [
|
||||
'_v' => 1,
|
||||
'id' => (string) $status->id,
|
||||
'shortcode' => HashidService::encode($status->id),
|
||||
'uri' => $status->url(),
|
||||
|
|
|
@ -7,19 +7,28 @@ use App\Media;
|
|||
|
||||
class Blurhash {
|
||||
|
||||
const DEFAULT_HASH = 'U4Rfzst8?bt7ogayj[j[~pfQ9Goe%Mj[WBay';
|
||||
|
||||
public static function generate(Media $media)
|
||||
{
|
||||
if(!in_array($media->mime, ['image/png', 'image/jpeg'])) {
|
||||
return;
|
||||
if(!in_array($media->mime, ['image/png', 'image/jpeg', 'video/mp4'])) {
|
||||
return self::DEFAULT_HASH;
|
||||
}
|
||||
|
||||
if($media->thumbnail_path == null) {
|
||||
return self::DEFAULT_HASH;
|
||||
}
|
||||
|
||||
$file = storage_path('app/' . $media->thumbnail_path);
|
||||
|
||||
if(!is_file($file)) {
|
||||
return;
|
||||
return self::DEFAULT_HASH;
|
||||
}
|
||||
|
||||
$image = imagecreatefromstring(file_get_contents($file));
|
||||
if(!$image) {
|
||||
return self::DEFAULT_HASH;
|
||||
}
|
||||
$width = imagesx($image);
|
||||
$height = imagesy($image);
|
||||
|
||||
|
@ -39,7 +48,7 @@ class Blurhash {
|
|||
$components_y = 4;
|
||||
$blurhash = BlurhashEngine::encode($pixels, $components_x, $components_y);
|
||||
if(strlen($blurhash) > 191) {
|
||||
return;
|
||||
return self::DEFAULT_HASH;
|
||||
}
|
||||
return $blurhash;
|
||||
}
|
||||
|
|
BIN
public/css/app.css
vendored
BIN
public/css/app.css
vendored
Binary file not shown.
BIN
public/css/appdark.css
vendored
BIN
public/css/appdark.css
vendored
Binary file not shown.
BIN
public/css/landing.css
vendored
BIN
public/css/landing.css
vendored
Binary file not shown.
BIN
public/js/hashtag.js
vendored
BIN
public/js/hashtag.js
vendored
Binary file not shown.
BIN
public/js/profile.js
vendored
BIN
public/js/profile.js
vendored
Binary file not shown.
Binary file not shown.
|
@ -36,8 +36,16 @@
|
|||
<div v-for="(tag, index) in top" class="col-4 p-0 p-sm-2 p-md-3 hashtag-post-square">
|
||||
<a class="card info-overlay card-md-border-0" :href="tag.status.url">
|
||||
<div :class="[tag.status.filter ? 'square ' + tag.status.filter : 'square']">
|
||||
<div v-if="tag.status.sensitive && forceNsfw == false" class="square-content" :style="'background-image: url(/storage/no-preview.png)'"></div>
|
||||
<div v-else class="square-content" :style="'background-image: url('+tag.status.thumb+')'"></div>
|
||||
<div v-if="tag.status.sensitive && forceNsfw == false" class="square-content">
|
||||
<blur-hash-image
|
||||
v-if="s.sensitive"
|
||||
width="32"
|
||||
height="32"
|
||||
punch="1"
|
||||
:hash="tag.status.media_attachments[0].blurhash"
|
||||
/>
|
||||
</div>
|
||||
<div v-else class="square-content" :style="'background-image: url('+tag.status.media_attachments[0].preview_url+')'"></div>
|
||||
<div class="info-overlay-text">
|
||||
<h5 class="text-white m-auto font-weight-bold">
|
||||
<span class="pr-4">
|
||||
|
@ -57,15 +65,38 @@
|
|||
<div v-for="(tag, index) in tags" class="col-4 p-0 p-sm-2 p-md-3 hashtag-post-square">
|
||||
<a class="card info-overlay card-md-border-0" :href="tag.status.url">
|
||||
<div :class="[tag.status.filter ? 'square ' + tag.status.filter : 'square']">
|
||||
<div v-if="tag.status.sensitive && forceNsfw == false" class="square-content" :style="'background-image: url(/storage/no-preview.png)'"></div>
|
||||
<div v-else class="square-content" :style="'background-image: url('+tag.status.thumb+')'"></div>
|
||||
<div v-if="tag.status.sensitive && forceNsfw == false" class="square-content">
|
||||
<div class="info-overlay-text-label">
|
||||
<h5 class="text-white m-auto font-weight-bold">
|
||||
<span>
|
||||
<span class="far fa-eye-slash fa-lg p-2 d-flex-inline"></span>
|
||||
</span>
|
||||
</h5>
|
||||
</div>
|
||||
<blur-hash-canvas
|
||||
width="32"
|
||||
height="32"
|
||||
:hash="tag.status.media_attachments[0].blurhash"
|
||||
/>
|
||||
</div>
|
||||
<div v-else class="square-content">
|
||||
<blur-hash-image
|
||||
width="32"
|
||||
height="32"
|
||||
:hash="tag.status.media_attachments[0].blurhash"
|
||||
:src="tag.status.media_attachments[0].preview_url"
|
||||
/>
|
||||
</div>
|
||||
<span v-if="tag.status.pf_type == 'photo:album'" class="float-right mr-3 post-icon"><i class="fas fa-images fa-2x"></i></span>
|
||||
<span v-if="tag.status.pf_type == 'video'" class="float-right mr-3 post-icon"><i class="fas fa-video fa-2x"></i></span>
|
||||
<span v-if="tag.status.pf_type == 'video:album'" class="float-right mr-3 post-icon"><i class="fas fa-film fa-2x"></i></span>
|
||||
<div class="info-overlay-text">
|
||||
<h5 class="text-white m-auto font-weight-bold">
|
||||
<span class="pr-4">
|
||||
<span class="far fa-heart fa-lg pr-1"></span> {{tag.status.like_count}}
|
||||
<span class="far fa-heart fa-lg pr-1"></span> {{tag.status.favourites_count}}
|
||||
</span>
|
||||
<span>
|
||||
<span class="fas fa-retweet fa-lg pr-1"></span> {{tag.status.share_count}}
|
||||
<span class="far fa-comment fa-lg pr-1"></span> {{tag.status.reply_count}}
|
||||
</span>
|
||||
</h5>
|
||||
</div>
|
||||
|
|
|
@ -183,21 +183,42 @@
|
|||
<div class="row" v-if="mode == 'grid'">
|
||||
<div class="col-4 p-1 p-md-3" v-for="(s, index) in timeline" :key="'tlob:'+index">
|
||||
<a class="card info-overlay card-md-border-0" :href="statusUrl(s)" v-once>
|
||||
<div :class="[s.sensitive ? 'square' : 'square ' + s.media_attachments[0].filter_class]">
|
||||
<div class="square">
|
||||
<div v-if="s.sensitive" class="square-content">
|
||||
<div class="info-overlay-text-label">
|
||||
<h5 class="text-white m-auto font-weight-bold">
|
||||
<span>
|
||||
<span class="far fa-eye-slash fa-lg p-2 d-flex-inline"></span>
|
||||
</span>
|
||||
</h5>
|
||||
</div>
|
||||
<blur-hash-canvas
|
||||
width="32"
|
||||
height="32"
|
||||
:hash="s.media_attachments[0].blurhash"
|
||||
/>
|
||||
</div>
|
||||
<div v-else class="square-content">
|
||||
|
||||
<blur-hash-image
|
||||
width="32"
|
||||
height="32"
|
||||
:hash="s.media_attachments[0].blurhash"
|
||||
:src="s.media_attachments[0].preview_url"
|
||||
/>
|
||||
</div>
|
||||
<span v-if="s.pf_type == 'photo:album'" class="float-right mr-3 post-icon"><i class="fas fa-images fa-2x"></i></span>
|
||||
<span v-if="s.pf_type == 'video'" class="float-right mr-3 post-icon"><i class="fas fa-video fa-2x"></i></span>
|
||||
<span v-if="s.pf_type == 'video:album'" class="float-right mr-3 post-icon"><i class="fas fa-film fa-2x"></i></span>
|
||||
<div class="square-content" v-bind:style="previewBackground(s)">
|
||||
</div>
|
||||
<div class="info-overlay-text">
|
||||
<h5 class="text-white m-auto font-weight-bold">
|
||||
<span>
|
||||
<span class="far fa-heart fa-lg p-2 d-flex-inline"></span>
|
||||
<span class="d-flex-inline">{{s.favourites_count}}</span>
|
||||
<span class="d-flex-inline">{{formatCount(s.favourites_count)}}</span>
|
||||
</span>
|
||||
<span>
|
||||
<span class="fas fa-retweet fa-lg p-2 d-flex-inline"></span>
|
||||
<span class="d-flex-inline">{{s.reblogs_count}}</span>
|
||||
<span class="far fa-comment fa-lg p-2 d-flex-inline"></span>
|
||||
<span class="d-flex-inline">{{formatCount(s.reply_count)}}</span>
|
||||
</span>
|
||||
</h5>
|
||||
</div>
|
||||
|
@ -818,6 +839,11 @@
|
|||
return 'background-image: url(' + preview + ');';
|
||||
},
|
||||
|
||||
blurhHashMedia(status) {
|
||||
return status.sensitive ? null :
|
||||
status.media_attachments[0].preview_url;
|
||||
},
|
||||
|
||||
switchMode(mode) {
|
||||
this.mode = _.indexOf(this.modes, mode) ? mode : 'grid';
|
||||
if(this.mode == 'bookmarks' && this.bookmarks.length == 0) {
|
||||
|
|
29
resources/assets/sass/custom.scss
vendored
29
resources/assets/sass/custom.scss
vendored
|
@ -131,6 +131,22 @@ body, button, input, textarea {
|
|||
background-color: rgba(0,0,0,0.5);
|
||||
}
|
||||
|
||||
.info-overlay-text-label {
|
||||
display: flex;
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: rgba(0,0,0,0.5);
|
||||
|
||||
h5 {
|
||||
z-index: 2;
|
||||
}
|
||||
}
|
||||
|
||||
.info-overlay:hover .info-overlay-text-label {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.font-weight-lighter {
|
||||
font-weight: 300 !important
|
||||
}
|
||||
|
@ -565,4 +581,17 @@ details summary::-webkit-details-marker {
|
|||
|
||||
.follow-modal {
|
||||
max-width: 400px !important;
|
||||
}
|
||||
|
||||
.square-content {
|
||||
img {
|
||||
object-fit: cover !important;
|
||||
}
|
||||
}
|
||||
|
||||
.square .square-content {
|
||||
canvas {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue