whoisthisstud's avatar

Livewire image previews not displaying on demo site

Temporary images display locally, but not on the demo site.

The images still upload, but the temporary URL's return a 404 error for each image uploaded, and attempting to load the signed URL in a different tab results in a 401.

I'm unsure if my issue is livewire, an error I created, or even possibly this - https://github.com/livewire/livewire/issues/1216 ?

Laravel 8 / Livewire 2 / Forge / DigitalOcean. The demo site is on a sub-domain, and not within a sub-folder. I've updated the upload sizes, the TrustedProxies, and the nginx config updates mentioned in the repo issue, but still have the same issue. I'd prefer not to comment out the abort_unless() line and lose CSRF protection - maybe temporarily for poo-poo's and haha's if requested.

Any and all help appreciated.

VIEW

<div class="w-full" x-data="{ progress: 0, isUploading: false }"
	x-on:livewire-upload-start="isUploading = true"
	x-on:livewire-upload-finish="isUploading = false"
	x-on:livewire-upload-error="isUploading = false"
	x-on:livewire-upload-progress="progress = $event.detail.progress">

	<label class="flex-col mb-2 text-sm font-bold text-gray-700" for="images">
		<div class="flex flex-row flex-no-wrap w-full h-16 sm:h-20 md:h-24 bg-gray-200 focus:outline-none cursor-pointer items-center text-center rounded border @error('images') border-red-600 @else border-gray-200 @enderror overflow-y-hidden overflow-x-scroll mb-3">
		
        		@if( ! empty( $images ) )	
				@foreach( $images as $image )
					@php
						$load = false;
						$ext = ['jpg','jpeg','png','webp','heic','heif'];
						if ( in_array( $image->guessExtension() ,  $ext ) ) {
							 $load = true;
						}
					@endphp
										
					@if($load)
					<div class="flex-none h-16 bg-no-repeat bg-center bg-cover mr-2 {{ $loop->first ? 'ml-4' : '' }}" style="background-image: url({{ $image->temporaryUrl() ?? '' }}); width: 100px;"></div>
					@else
					<div class="block w-16">
						<span class="text-sm text-red-600">
							<span class="uppercase">{{ $image->guessExtension() }}</span> is an invalid filetype. An image is required.
						</span>
					</div>
					@endif
				@endforeach
			@else
			<div class="block w-full">
				<span class="w-full self-center mx-auto @error('images') text-red-600 @else text-gray-700 @enderror text-gray-700 font-bold">Upload Image</span>
				@error('images')
				<p class="w-full text-red-500 mt-1 text-sm font-normal pb-2 hidden md:block">{{ $message }}</p>
				@enderror
			</div>							
			@endif														
		</div>
		<input wire:model="images" class="w-full px-3 py-2 text-base leading-tight border border-gray-200 bg-gray-200 focus:bg-white text-gray-700 rounded shadow appearance-none hidden"
			id="images" name="images" type="file" multiple />
	</label>
        <div wire:loading wire:target="images" class="w-full my-2 text-red-600 text-center font-bold">Uploading...</div>
</div>

CONTROLLER

namespace App\Http\Livewire;

use Image;
use Storage;
use Livewire\Component;
use Livewire\WithFileUploads;
use Illuminate\Validation\ValidationException;


class XXXXX extends Component
{
    use WithFileUploads;

    public $images = [];
    public $imageList = [];

    [...]

    public function goToStepThree()
	{

		if( empty( $this->images ) ) {
			throw ValidationException::withMessages( ['images' => 'At least one image is required.'] );
		}

		// Get rid of any old images
		if( count( $this->imageList ) > 0 ) {
			foreach( $this->imageList as $oldImage ) {
				Storage::delete( $oldImage );
			}
			$this->reset( 'imageList' );
		}

		// Resize and store each image
		foreach( $this->images as $image ) {
			$this->resizeAndStoreTheImage( $image );
		}

		[...]

	}

    protected function resizeAndStoreTheImage( $image ) 
	{
		// Set the new image's name
	    $filename = time() . '-' . mt_rand( 10000 , 1000000 );
	    $filename_w_ext = $filename . '.' . $image->extension();

		// Save original uploaded image
		$original_image = $image->storeAs( 'ticket-request-images' , $filename_w_ext );

		// Get the original uploaded image's details
		list( $original_image_width, 
			$original_image_height, 
			$original_image_type, 
			$original_image_attr 
		) = getimagesize( Storage::path( $original_image ) );

		// Define new sizes
		$newSizes = [
			'xs' => [
				'size' => 250,
				'quality' => 60
			],
			'md' => [
				'size' => 600,
				'quality' => 70
			],
			'lg' => [
				'size' => 1024,
				'quality' => 80
			],
			'xl' => [
				'size' => 2048,
				'quality' => 90
			],
		];

		
		$thumbs = [];

		while( $this_new_size = current( $newSizes ) ) {

			// Get the size key, i.e. 'xs','md','lg'...
			$key = key( $newSizes );

			// Create a dynamic variable for folder path
			${$key} = Image::make( Storage::path( $original_image ) );

			// If the height or width of image is greater than newSizes size
			if( $original_image_width > $this_new_size['size'] || $original_image_height > $this_new_size['size'] ) {

				// Resize images - constrain to the new size's size on either side
				${$key}->resize( $this_new_size['size'] , $this_new_size['size'] , function ($constraint){

			    	$constraint->aspectRatio();

				})->stream( 'jpeg' , $this_new_size['quality'] );

				// Set the location
				$location = 'ticket-request-images/thumbnails/' . $key . '/' . $filename . '.jpg';

				// Store the resized image
				Storage::put( $location , ${$key} );

				// Push the location to the thumbs array
				array_push( $thumbs , $location );

			}

		    next($newSizes);

		}

		// Add the location to the imageList array
		array_push( $this->imageList, $thumbs );

		// Delete original, non-resized image
		Storage::delete( $original_image );
	}
0 likes
0 replies

Please or to participate in this conversation.