mirror of
https://github.com/pixelfed/pixelfed.git
synced 2024-11-22 22:41:27 +00:00
commit
cf0943a00a
10 changed files with 143 additions and 137 deletions
|
@ -30,8 +30,8 @@ class StatusController extends Controller
|
|||
$user = Auth::user();
|
||||
|
||||
$this->validate($request, [
|
||||
'photo' => 'required|image|max:15000',
|
||||
'caption' => 'string|max:150'
|
||||
'photo' => 'required|mimes:jpeg,png,bmp,gif|max:' . config('pixelfed.max_photo_size'),
|
||||
'caption' => 'string|max:' . config('pixelfed.max_caption_length')
|
||||
]);
|
||||
|
||||
$monthHash = hash('sha1', date('Y') . date('m'));
|
||||
|
|
|
@ -40,7 +40,6 @@ class AppServiceProvider extends ServiceProvider
|
|||
});
|
||||
|
||||
Blade::directive('prettySize', function($expression) {
|
||||
|
||||
$size = intval($expression);
|
||||
$precision = 0;
|
||||
$short = true;
|
||||
|
@ -51,6 +50,11 @@ class AppServiceProvider extends ServiceProvider
|
|||
$res = round($size, $precision).$units[$i];
|
||||
return "<?php echo '$res'; ?>";
|
||||
});
|
||||
|
||||
Blade::directive('maxFileSize', function() {
|
||||
$value = config('pixelfed.max_photo_size');
|
||||
return \App\Util\Lexer\PrettyNumber::size($value, true);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -17,4 +17,20 @@ class PrettyNumber {
|
|||
return $expression;
|
||||
}
|
||||
|
||||
public static function size($expression, $kb = false)
|
||||
{
|
||||
if($kb) {
|
||||
$expression = $expression * 1024;
|
||||
}
|
||||
$size = intval($expression);
|
||||
$precision = 0;
|
||||
$short = true;
|
||||
$units = $short ?
|
||||
['B','k','M','G','T','P','E','Z','Y'] :
|
||||
['B','kB','MB','GB','TB','PB','EB','ZB','YB'];
|
||||
for($i = 0; ($size / 1024) > 0.9; $i++, $size /= 1024) {}
|
||||
$res = round($size, $precision).$units[$i];
|
||||
return $res;
|
||||
}
|
||||
|
||||
}
|
|
@ -105,42 +105,25 @@ class Image {
|
|||
$orientation = $ratio['orientation'];
|
||||
|
||||
try {
|
||||
$img = Intervention::make($file);
|
||||
$img = Intervention::make($file)->orientate();
|
||||
$img->resize($aspect['width'], $aspect['height'], function ($constraint) {
|
||||
$constraint->aspectRatio();
|
||||
});
|
||||
$converted = $this->convertPngToJpeg($path, $thumbnail, $img->extension);
|
||||
$converted = $this->setBaseName($path, $thumbnail, $img->extension);
|
||||
$newPath = storage_path('app/'.$converted['path']);
|
||||
$is_png = false;
|
||||
|
||||
if($img->extension == 'png' || $converted['png'] == true) {
|
||||
\Log::info('PNG detected, ' . json_encode([$img, $converted]));
|
||||
$is_png = true;
|
||||
$newPath = str_replace('.png', '.jpeg', $newPath);
|
||||
$img->encode('jpg', 80)->save($newPath);
|
||||
if(!$thumbnail) {
|
||||
@unlink($file);
|
||||
}
|
||||
\Log::info('PNG SAVED, ' . json_encode([$img, $newPath]));
|
||||
} else {
|
||||
\Log::info('PNG not detected, ' . json_encode([$img, $converted]));
|
||||
$img->save($newPath, 75);
|
||||
}
|
||||
$img->save($newPath, 75);
|
||||
|
||||
if(!$thumbnail) {
|
||||
$media->orientation = $orientation;
|
||||
}
|
||||
|
||||
if($is_png == true) {
|
||||
if($thumbnail == false) {
|
||||
if($thumbnail == true) {
|
||||
$media->thumbnail_path = $converted['path'];
|
||||
$media->thumbnail_url = url(Storage::url($converted['path']));
|
||||
} else {
|
||||
$media->media_path = $converted['path'];
|
||||
$media->mime = $img->mime;
|
||||
}
|
||||
}
|
||||
|
||||
if($thumbnail == true) {
|
||||
$media->thumbnail_path = $converted['path'];
|
||||
$media->thumbnail_url = url(Storage::url($converted['path']));
|
||||
}
|
||||
|
||||
$media->save();
|
||||
|
@ -150,18 +133,14 @@ class Image {
|
|||
}
|
||||
}
|
||||
|
||||
public function convertPngToJpeg($basePath, $thumbnail = false, $extension)
|
||||
public function setBaseName($basePath, $thumbnail = false, $extension)
|
||||
{
|
||||
$png = false;
|
||||
$path = explode('.', $basePath);
|
||||
$name = ($thumbnail == true) ? $path[0] . '_thumb' : $path[0];
|
||||
$ext = last($path);
|
||||
$basePath = "{$name}.{$ext}";
|
||||
if($extension == 'png' || $ext == 'png') {
|
||||
$ext = 'jpeg';
|
||||
$basePath = "{$name}.{$ext}";
|
||||
$png = true;
|
||||
}
|
||||
|
||||
return ['path' => $basePath, 'png' => $png];
|
||||
}
|
||||
|
||||
|
|
|
@ -77,4 +77,24 @@ return [
|
|||
|
||||
'activitypub_enabled' => env('ACTIVITY_PUB', false),
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Photo file size limit
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Update the max photo size, in KB.
|
||||
|
|
||||
*/
|
||||
'max_photo_size' => env('MAX_PHOTO_SIZE', 15000),
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Caption limit
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Change the caption length limit for new local posts.
|
||||
|
|
||||
*/
|
||||
'max_caption_length' => env('MAX_CAPTION_LENGTH', 150),
|
||||
|
||||
];
|
4
resources/assets/sass/custom.scss
vendored
4
resources/assets/sass/custom.scss
vendored
|
@ -56,9 +56,7 @@ body, button, input, textarea {
|
|||
}
|
||||
|
||||
.card.status-container .status-photo {
|
||||
display: -webkit-box !important;
|
||||
display: -ms-flexbox !important;
|
||||
display: flex !important;
|
||||
display: block !important;
|
||||
margin: auto !important;
|
||||
}
|
||||
|
||||
|
|
|
@ -2,82 +2,78 @@
|
|||
|
||||
@section('content')
|
||||
|
||||
<div class="container">
|
||||
<div class="col-12 mt-4">
|
||||
|
||||
<div class="card status-container orientation-{{$status->firstMedia()->orientation ?? 'unknown'}}">
|
||||
<div class="card-body p-0">
|
||||
<div class="row">
|
||||
<div class="col-12 col-md-8 status-photo">
|
||||
<img src="{{$status->mediaUrl()}}" width="100%">
|
||||
<div class="container px-0 mt-md-4">
|
||||
<div class="card status-container orientation-{{$status->firstMedia()->orientation ?? 'unknown'}}">
|
||||
<div class="row mx-0">
|
||||
<div class="col-12 col-md-8 status-photo px-0">
|
||||
<img src="{{$status->mediaUrl()}}" width="100%">
|
||||
</div>
|
||||
<div class="col-12 col-md-4 px-0 d-flex flex-column">
|
||||
<div class="d-flex align-items-center justify-content-between card-header">
|
||||
<div class="d-flex align-items-center status-username">
|
||||
<div class="status-avatar mr-2">
|
||||
<img class="img-thumbnail" src="{{$user->avatarUrl()}}" width="24px" height="24px" style="border-radius:12px;">
|
||||
</div>
|
||||
<div class="username">
|
||||
<a href="{{$user->url()}}" class="username-link font-weight-bold text-dark">{{$user->username}}</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 col-md-4" style="height:100%">
|
||||
<div class="status-username d-inline-flex align-items-center pr-3 pt-3">
|
||||
<div class="status-avatar mr-2">
|
||||
<img class="img-thumbnail" src="{{$user->avatarUrl()}}" width="50px" height="50px" style="border-radius:40px;">
|
||||
</div>
|
||||
<div class="username">
|
||||
<a href="{{$user->url()}}" class="username-link font-weight-bold text-dark">{{$user->username}}</a>
|
||||
</div>
|
||||
</div>
|
||||
<hr>
|
||||
<div class="pr-3 mb-2 status-comments">
|
||||
<div class="status-comment">
|
||||
<span class="font-weight-bold pr-1">{{$status->profile->username}}</span>
|
||||
<p class="mb-1">
|
||||
<span class="comment-text">{!! $status->rendered ?? e($status->caption) !!}</span>
|
||||
</p>
|
||||
<div class="comments">
|
||||
<div class="timestamp mb-0">
|
||||
<p class="small text-uppercase mb-0"><a href="{{$status->url()}}" class="text-muted">{{$status->created_at->diffForHumans()}}</a></p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body status-comments">
|
||||
<div class="status-comment">
|
||||
<p class="mb-1">
|
||||
<span class="font-weight-bold pr-1">{{$status->profile->username}}</span>
|
||||
<span class="comment-text">{!! $status->rendered ?? e($status->caption) !!}</span>
|
||||
</p>
|
||||
<div class="comments">
|
||||
@foreach($status->comments->reverse()->take(10) as $item)
|
||||
<p class="mb-0">
|
||||
<span class="font-weight-bold pr-1"><bdi><a class="text-dark" href="{{$item->profile->url()}}">{{$item->profile->username}}</a></bdi></span>
|
||||
<span class="comment-text">{!!$item->rendered!!} <a href="{{$item->url()}}" class="text-dark small font-weight-bold float-right">{{$item->created_at->diffForHumans(null, true, true ,true)}}</a></span>
|
||||
</p>
|
||||
<p class="mb-0">
|
||||
<span class="font-weight-bold pr-1"><bdi><a class="text-dark" href="{{$item->profile->url()}}">{{$item->profile->username}}</a></bdi></span>
|
||||
<span class="comment-text">{!!$item->rendered!!} <a href="{{$item->url()}}" class="text-dark small font-weight-bold float-right">{{$item->created_at->diffForHumans(null, true, true ,true)}}</a></span>
|
||||
</p>
|
||||
@endforeach
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="reactions h3 pr-3 mb-0">
|
||||
<form class="like-form pr-3" method="post" action="/i/like" style="display: inline;" data-id="{{$status->id}}" data-action="like">
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body flex-grow-0">
|
||||
<div class="reactions h3 mb-0">
|
||||
<form class="d-inline-flex like-form pr-3" method="post" action="/i/like" style="display: inline;" data-id="{{$status->id}}" data-action="like">
|
||||
@csrf
|
||||
<input type="hidden" name="item" value="{{$status->id}}">
|
||||
<button class="btn btn-link text-dark p-0" type="submit"><span class="icon-heart" style="font-size:25px;"></span></button>
|
||||
<button class="btn btn-link text-dark p-0" type="submit"><h3 class="icon-heart mb-0"></h3></button>
|
||||
</form>
|
||||
<span class="icon-speech pr-3"></span>
|
||||
@if(Auth::check())
|
||||
@if(Auth::user()->profile->id === $status->profile->id || Auth::user()->is_admin == true)
|
||||
<form method="post" action="/i/delete" class="d-inline-flex">
|
||||
@csrf
|
||||
<input type="hidden" name="type" value="post">
|
||||
<input type="hidden" name="item" value="{{$status->id}}">
|
||||
<button type="submit" class="btn btn-link text-dark p-0"><span class="icon-trash" style="font-size:25px;"></span></button>
|
||||
</form>
|
||||
@endif
|
||||
@endif
|
||||
<span class="float-right">
|
||||
<form class="bookmark-form" method="post" action="/i/bookmark" style="display: inline;" data-id="{{$status->id}}" data-action="bookmark">
|
||||
@csrf
|
||||
<input type="hidden" name="item" value="{{$status->id}}">
|
||||
<button class="btn btn-link text-dark p-0" type="submit"><span class="icon-notebook" style="font-size:25px;"></span></button>
|
||||
</form>
|
||||
</span>
|
||||
</div>
|
||||
<div class="likes font-weight-bold mb-0">
|
||||
<span class="like-count">{{$status->likes()->count()}}</span> likes
|
||||
</div>
|
||||
<div class="timestamp mb-0">
|
||||
<p class="small text-uppercase mb-0"><a href="{{$status->url()}}" class="text-muted">{{$status->created_at->diffForHumans()}}</a></p>
|
||||
</div>
|
||||
<hr class="my-2">
|
||||
<div class="pr-3 pb-2">
|
||||
<form class="comment-form" method="post" action="/i/comment" data-id="{{$status->id}}" data-truncate="false">
|
||||
<span class="icon-speech pr-3"></span>
|
||||
@if(Auth::check())
|
||||
@if(Auth::user()->profile->id === $status->profile->id || Auth::user()->is_admin == true)
|
||||
<form method="post" action="/i/delete" class="d-inline-flex">
|
||||
@csrf
|
||||
<input type="hidden" name="type" value="post">
|
||||
<input type="hidden" name="item" value="{{$status->id}}">
|
||||
<button type="submit" class="btn btn-link text-dark p-0"><h3 class="icon-trash mb-0"></h3></button>
|
||||
</form>
|
||||
@endif
|
||||
@endif
|
||||
<span class="float-right">
|
||||
<form class="d-inline-flex bookmark-form" method="post" action="/i/bookmark" style="display: inline;" data-id="{{$status->id}}" data-action="bookmark">
|
||||
@csrf
|
||||
<input type="hidden" name="item" value="{{$status->id}}">
|
||||
<input class="form-control" name="comment" placeholder="Add a comment...">
|
||||
<button class="btn btn-link text-dark p-0" type="submit"><h3 class="icon-notebook mb-0"></h3></button>
|
||||
</form>
|
||||
</div>
|
||||
</span>
|
||||
</div>
|
||||
<div class="likes font-weight-bold mb-0">
|
||||
<span class="like-count">{{$status->likes()->count()}}</span> likes
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-footer">
|
||||
<form class="comment-form" method="post" action="/i/comment" data-id="{{$status->id}}" data-truncate="false">
|
||||
@csrf
|
||||
<input type="hidden" name="item" value="{{$status->id}}">
|
||||
<input class="form-control" name="comment" placeholder="Add a comment...">
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
23
resources/views/timeline/partial/new-form.blade.php
Normal file
23
resources/views/timeline/partial/new-form.blade.php
Normal file
|
@ -0,0 +1,23 @@
|
|||
<div class="card">
|
||||
<div class="card-header font-weight-bold">New Post</div>
|
||||
<div class="card-body" id="statusForm">
|
||||
<form method="post" action="/timeline" enctype="multipart/form-data">
|
||||
@csrf
|
||||
<div class="form-group">
|
||||
<label class="font-weight-bold text-muted small">Upload Image</label>
|
||||
<input type="file" class="form-control-file" name="photo" accept="image/*">
|
||||
<small class="form-text text-muted">
|
||||
Max Size: @maxFileSize(). Supported formats: jpeg, png, gif, bmp.
|
||||
</small>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="font-weight-bold text-muted small">Caption</label>
|
||||
<input type="text" class="form-control" name="caption" placeholder="Add a caption here">
|
||||
<small class="form-text text-muted">
|
||||
Max length: {{config('pixelfed.max_caption_length')}} characters.
|
||||
</small>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-outline-primary btn-block">Post</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
|
@ -17,23 +17,8 @@
|
|||
</ul>
|
||||
</div>
|
||||
@endif
|
||||
<div class="card">
|
||||
<div class="card-header font-weight-bold">New Post</div>
|
||||
<div class="card-body" id="statusForm">
|
||||
<form method="post" action="/timeline" enctype="multipart/form-data">
|
||||
@csrf
|
||||
<div class="form-group">
|
||||
<label class="font-weight-bold text-muted small">Upload Image</label>
|
||||
<input type="file" class="form-control-file" name="photo" accept="image/*">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="font-weight-bold text-muted small">Caption</label>
|
||||
<input type="text" class="form-control" name="caption" placeholder="Add a caption here">
|
||||
</div>
|
||||
<button type="submit" class="btn btn-outline-primary btn-block">Post</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@include('timeline.partial.new-form')
|
||||
|
||||
<div class="timeline-feed my-5" data-timeline="personal">
|
||||
@foreach($timeline as $item)
|
||||
|
|
|
@ -17,23 +17,8 @@
|
|||
</ul>
|
||||
</div>
|
||||
@endif
|
||||
<div class="card">
|
||||
<div class="card-header font-weight-bold">New Post</div>
|
||||
<div class="card-body" id="statusForm">
|
||||
<form method="post" action="/timeline" enctype="multipart/form-data">
|
||||
@csrf
|
||||
<div class="form-group">
|
||||
<label class="font-weight-bold text-muted small">Upload Image</label>
|
||||
<input type="file" class="form-control-file" name="photo" accept="image/*">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="font-weight-bold text-muted small">Caption</label>
|
||||
<input type="text" class="form-control" name="caption" placeholder="Add a caption here">
|
||||
</div>
|
||||
<button type="submit" class="btn btn-outline-primary btn-block">Post</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@include('timeline.partial.new-form')
|
||||
|
||||
<div class="timeline-feed my-5" data-timeline="public">
|
||||
@foreach($timeline as $item)
|
||||
|
|
Loading…
Reference in a new issue