Generate multiple avatar sizes for better performance loading and frugal traffic

This commit is contained in:
Čarodej
2021-11-03 16:28:14 +01:00
parent dc8ec5f20b
commit f139dbae08
30 changed files with 280 additions and 152 deletions

View File

@@ -2,6 +2,7 @@
namespace Domain\Files\Actions;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Str;
use Intervention\Image\ImageManagerStatic as Image;
class CreateImageThumbnailAction
@@ -18,34 +19,31 @@ class CreateImageThumbnailAction
* Create image thumbnail from uploaded image
*/
public function __invoke(
string $file_path,
string $filename,
string $file_name,
$file,
string $user_id
): string | null {
$mimeType = Storage::disk('local')->mimeType($file_path);
): void {
// Create thumbnail from image
if (in_array($mimeType, $this->availableFormats)) {
// Get thumbnail name
$thumbnail = "thumbnail-$filename";
if (in_array($file->getClientMimeType(), $this->availableFormats)) {
// Create intervention image
$image = Image::make(Storage::disk('local')
->path($file_path))
->orientate();
$intervention = Image::make($file)->orientate();
// Resize image
$image->resize(512, null, fn ($constraint) => $constraint->aspectRatio())->stream();
// Generate avatar sizes
collect(config('vuefilemanager.image_sizes'))
->each(function ($size) use ($intervention, $file_name, $user_id) {
// Store thumbnail to disk
Storage::put("files/$user_id/$thumbnail", $image);
// Create thumbnail only if image is larger than predefined image sizes
if ($intervention->getWidth() > $size['size']) {
// Generate thumbnail
$intervention->resize($size['size'], null, fn ($constraint) => $constraint->aspectRatio())->stream();
// Store thumbnail to disk
Storage::put("files/$user_id/{$size['name']}-{$file_name}", $intervention);
}
});
}
// Return thumbnail as svg file
if ($mimeType === 'image/svg+xml') {
return $filename;
}
return $thumbnail ?? null;
}
}

View File

@@ -11,18 +11,28 @@ class DownloadThumbnailAction
* Get image thumbnail for browser
*/
public function __invoke(
File $file,
string $user_id
string $filename,
File $file
): StreamedResponse {
// Get file path
$path = "/files/$user_id/{$file->getRawOriginal('thumbnail')}";
$path = "/files/$file->user_id/$filename";
// Check if file exist
if (! Storage::exists($path)) {
abort(404);
// Get original file path
$substituteFilePath = "/files/$file->user_id/$file->basename";
// Check if original file exist
if (! Storage::exists($substituteFilePath)) {
abort(404);
}
// Return image thumbnail
return Storage::download($substituteFilePath, $filename);
}
// Return image thumbnail
return Storage::download($path, $file->getRawOriginal('thumbnail'));
return Storage::download($path, $filename);
}
}

View File

@@ -9,6 +9,7 @@ use Domain\Files\Requests\UploadRequest;
use Domain\Files\Models\File as UserFile;
use Domain\Traffic\Actions\RecordUploadAction;
use App\Users\Actions\CheckStorageCapacityAction;
use Illuminate\Support\Str;
class UploadFileAction
{
@@ -27,27 +28,27 @@ class UploadFileAction
UploadRequest $request,
?Share $shared = null,
) {
// Get parent_id from request
$file = $request->file('file');
$chunkName = $file->getClientOriginalName();
// File name
$disk_file_name = basename('chunks/' . $file->getClientOriginalName(), '.part');
$temp_filename = $file->getClientOriginalName();
$fileName = Str::uuid() . '.' . $file->extension();
// File Path
$file_path = Storage::disk('local')->path('chunks/' . $temp_filename);
$filePath = Storage::disk('local')->path('chunks/' . $chunkName);
// Generate file
File::append($file_path, $file->get());
File::append($filePath, $file->get());
// Size of file
$file_size = File::size($file_path);
$fileSize = File::size($filePath);
// Size of limit
$limit = get_settings('upload_limit');
$uploadLimit = get_settings('upload_limit');
// File size handling
if ($limit && $file_size > format_bytes($limit)) {
if ($uploadLimit && $fileSize > format_bytes($uploadLimit)) {
abort(413);
}
@@ -61,26 +62,26 @@ class UploadFileAction
$user_id = $shared->user_id ?? Auth::id();
// File Info
$file_size = $disk_local->size("chunks/$temp_filename");
$fileSize = $disk_local->size("chunks/$chunkName");
$file_mimetype = $disk_local->mimeType("chunks/$temp_filename");
$file_mimetype = $disk_local->mimeType("chunks/$chunkName");
// Check if user has enough space to upload file
($this->checkStorageCapacity)($user_id, $file_size, $temp_filename);
($this->checkStorageCapacity)($user_id, $fileSize, $chunkName);
// Create thumbnail
$thumbnail = ($this->createImageThumbnail)("chunks/$temp_filename", $disk_file_name, $user_id);
// Create multiple image thumbnails
($this->createImageThumbnail)($fileName, $file, $user_id);
// Move finished file from chunk to file-manager directory
$disk_local->move("chunks/$temp_filename", "files/$user_id/$disk_file_name");
$disk_local->move("chunks/$chunkName", "files/$user_id/$fileName");
// Move files to external storage
if (! is_storage_driver(['local'])) {
($this->moveFileToExternalStorage)($disk_file_name, $user_id);
($this->moveFileToExternalStorage)($fileName, $user_id);
}
// Store user upload size
($this->recordUpload)($file_size, $user_id);
($this->recordUpload)($fileSize, $user_id);
// Return new file
return UserFile::create([
@@ -89,10 +90,9 @@ class UploadFileAction
'parent_id' => $request->input('parent_id'),
'metadata' => $metadata,
'name' => $request->input('filename'),
'basename' => $disk_file_name,
'basename' => $fileName,
'author' => $shared ? 'visitor' : 'user',
'thumbnail' => $thumbnail,
'filesize' => $file_size,
'filesize' => $fileSize,
'user_id' => $user_id,
]);
}