diff --git a/.github/workflows/phpstan.yml b/.github/workflows/phpstan.yml
index ccfa9d9..e2aabdc 100644
--- a/.github/workflows/phpstan.yml
+++ b/.github/workflows/phpstan.yml
@@ -16,7 +16,7 @@ jobs:
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
- php-version: '8.1'
+ php-version: '8.2'
coverage: none
- name: Install composer dependencies
diff --git a/.github/workflows/run-tests.yml b/.github/workflows/run-tests.yml
index b74e2ef..93daafd 100644
--- a/.github/workflows/run-tests.yml
+++ b/.github/workflows/run-tests.yml
@@ -13,13 +13,19 @@ jobs:
fail-fast: true
matrix:
os: [ubuntu-latest]
- php: [8.2, 8.1]
- laravel: [10.*]
+ php: [8.3,8.2, 8.1]
+ laravel: [10.*,11.*]
stability: [prefer-stable]
include:
+ - laravel: 11.*
+ testbench: 9.*
+ carbon: ^2.63
- laravel: 10.*
testbench: 8.*
carbon: ^2.63
+ exclude:
+ - laravel: 11.*
+ php: 8.1
name: P${{ matrix.php }} - L${{ matrix.laravel }} - ${{ matrix.stability }} - ${{ matrix.os }}
diff --git a/composer.json b/composer.json
index 43d599e..1eaf63e 100644
--- a/composer.json
+++ b/composer.json
@@ -25,15 +25,15 @@
"require": {
"php": "^8.1",
"filament/filament": "^3.0",
- "illuminate/contracts": "^10.0",
- "spatie/image": "^2.2",
+ "illuminate/contracts": "^10.0|^11.0",
+ "spatie/image": "^2.2|^3.0",
"spatie/laravel-package-tools": "^1.15.0"
},
"require-dev": {
"laravel/pint": "^1.0",
- "nunomaduro/collision": "^7.9",
+ "nunomaduro/collision": "^7.9|^8.0",
"larastan/larastan": "^2.0.1",
- "orchestra/testbench": "^8.0",
+ "orchestra/testbench": "^8.0|^9.0",
"pestphp/pest": "^2.0",
"pestphp/pest-plugin-arch": "^2.0",
"pestphp/pest-plugin-laravel": "^2.0",
diff --git a/config/gallery-json-media.php b/config/gallery-json-media.php
index 710b332..cfedb6b 100644
--- a/config/gallery-json-media.php
+++ b/config/gallery-json-media.php
@@ -3,7 +3,6 @@
declare(strict_types=1);
// config for WebplusMultimedia\GalleryJsonMedia
-use Spatie\Image\Manipulations;
return [
'disk' => 'public',
@@ -13,7 +12,7 @@
'signing_key' => 'app.key',
'driver' => 'imagick', // gd or imagick
'quality' => 80,
- 'thumbnails-crop-method' => Manipulations::CROP_CENTER,
+ 'thumbnails-crop-method' => null,
'thumbnails-saved-format' => null, // Manipulations::FORMAT_PNG / following formats are supported: FORMAT_JPG, FORMAT_PJPG, FORMAT_PNG, FORMAT_GIF, FORMAT_WEBP and FORMAT_TIFF
],
diff --git a/resources/dist/components/gallery-json-media.js b/resources/dist/components/gallery-json-media.js
index ce59cb2..627efe5 100644
--- a/resources/dist/components/gallery-json-media.js
+++ b/resources/dist/components/gallery-json-media.js
@@ -1,4 +1,4 @@
-function u(i){return i?i>1e3*1e3?((i/(1e3*1e3)).toFixed(1)+" Mb").replace(".",","):i>1024?((i/1e3).toFixed(1)+" kb").replace(".",","):(i.toFixed(1)+" *kb").replace(".",","):"unknow size"}function f(i,s){return i instanceof File?{name:i.name,size:i.size,mime_type:i.type,is_new:!0,is_success:!1,error:!1,filekey:s,progress:0,url:URL.createObjectURL(i)}:!1}function w(i){return{_minSize:null,_maxSize:null,_acceptedFileTypes:null,minSize(s){return this._minSize=s,this},maxSize(s){return this._maxSize=s,this},fileType(s){return this._acceptedFileTypes=s,this},check(){return!U(i,this._acceptedFileTypes)||!z(i,this._maxSize)||!M(i,this._minSize)}}}function F(i,s,p){let o=i.length+p;return!(s&&o>s)}function M(i,s){return!(s&&i.size>s)}function z(i,s){return!(s&&i.size>s*1024)}function U(i,s){return s?s.filter(o=>o===i.type).length>0:!0}function m(){return("10000000-1000-4000-8000"+-1e11).replace(/[018]/g,i=>(i^crypto.getRandomValues(new Uint8Array(1))[0]&15>>i/4).toString(16))}function x(i){return{xls(){return``},getFile(){try{if(i.mime_type.startsWith("image"))return``;if(i.name.toLowerCase().endsWith(".pdf"))return this.pdf();if(i.name.toLowerCase().endsWith(".xls")||i.name.toLowerCase().endsWith(".xlsx"))return this.xls();if(i.name.toLowerCase().endsWith(".doc")||i.name.toLowerCase().endsWith(".docx"))return this.word()}catch{}return this.unKnown()}}}function A({state:i,statePath:s,minSize:c,maxSize:h,maxFiles:u,isMultiple:O,isDeletable:H,isDisabled:Z,isDownloadable:_,uploadingMessage:B,isReorderable:L,acceptedFileTypes:b,hasCustomPropertiesAction:V,deleteUploadedFileUsing:D,getUploadedFilesUsing:S,removeUploadedFileUsing:$,customPropertyActionName:k,reorderUploadedFilesUsing:M}){return{state:i,statePath:s,customPropertyActionName:k,hasCustomPropertiesAction:V,isDeletable:H,isReorderable:L,lastState:null,uploadFiles:[],uploadedFileIndex:{},editingFile:{},startUpload:!1,fileKeyIndex:{},progress:0,_startSwipeX:0,stopDragging:!0,getHumanSize(e){return w(e)},uploadUsing:(e,t,r,n,d,p)=>{this.$wire.upload(`${s}.${e}`,t,g=>{r(p)},()=>{n(p)},g=>{d(p,g)})},getFileName:function(e){if(e.startsWith("blob:")||e.startsWith("livewire:"))return e;let t=e.lastIndexOf("/");return t!==-1?e.slice(t+1):e},getContentImage(e){return y(e).getFile()},saveFilesUsing(e){let t=this.$refs.galleryImages,r=function(l){let o=l.uploadFiles.filter(a=>a.is_success===!1).length,f=l.uploadFiles.filter(a=>a.error===!0).length;o-f===0&&(l.dispatchFormEvent("form-processing-finished"),f&&(l.uploadFiles=l.uploadFiles.filter(a=>!a.error).map(a=>(a.error=!1,a))),l.startUpload=!1)},n=l=>{this.uploadFiles[l].is_success=!0,this.uploadFiles[l].progress=0,r(this)},d=l=>{this.uploadFiles[l].progress=0,this.uploadFiles[l].error=!0,r(this)},p=(l,o)=>{this.uploadFiles[l].progress=o.detail.progress},g=e.length,C=0;if(g){if(!x(e,u,g)){new FilamentNotification().title("Max Files reach").danger().send();return}this.startUpload||this.dispatchFormEvent("form-processing-started",{message:B}),this.startUpload=!0;for(let l of Array.from(e)){if(m(l).fileType(b).maxSize(h).minSize(c).check()){new FilamentNotification().title(`File "${l.name}" invalid`).warning().send();continue}let o=F(l,v());o&&(this.uploadFiles.push({...o}),this.uploadUsing(o.filekey,l,n,d,p,this.uploadFiles.length-1),C++)}setTimeout(()=>{t.scrollTo({left:t.scrollWidth,behavior:"smooth"})},30),C===0&&(this.startUpload=!1,this.dispatchFormEvent("form-processing-finished"))}},laFileInput:{async"@change"(){let e=this.$event.target.files;await this.saveFilesUsing(e)}},onScrolling:{"@wheel.stop"(e){let t=Object.entries(this.uploadFiles).length,r=this.$refs.galleryImages,n=this.$refs.ulGalleryWrapper;if(t*320>r.clientWidth){let d=e.deltaY<0?-280:280;(e.deltaY>0&&r.scrollLeft>=0&&r.scrollLeft+r.clientWidth0)&&(e.preventDefault(),r.scrollTo({left:r.scrollLeft+d,behavior:"smooth"}))}}},pointerNone:{"@pointerenter"(e){let t=this.$refs.galleryImages;t.style.pointerEvents="none"},"@pointerleave"(e){let t=this.$refs.galleryImages;t.style.pointerEvents="auto"}},dropZone:{"@click.prevent.stop"(){this.$refs.laFileInput.click()},"@dragover.prevent.stop"(){this.$event.target.classList.contains("wm-json-media-dropzone")},async"@drop.prevent.stop"(){this.$event.target.classList.contains("wm-json-media-dropzone")&&(await this.saveFilesUsing(this.$event.dataTransfer.files),this.$refs.dropzone.classList.remove("wm-dropzone"))},"@dragenter.prevent.stop"(){this.$refs.dropzone.classList.add("wm-dropzone")},"@dragleave.prevent.stop"(){return this.$event.target===this.$refs.dropzone&&this.$refs.dropzone.classList.remove("wm-dropzone"),!1}},leftArrow:{"@click.stop"(){let e=Object.entries(this.uploadFiles).length,t=this.$refs.galleryImages;t.scrollLeft>0&&t.scroll({left:t.scrollLeft-300,behavior:"smooth"})}},rightArrow:{"@click.stop"(){let e=this.$refs.galleryImages;e.scrollLeft+e.clientWidthr?.url).reduce((t,[r,n])=>(t[n.url]=r,t),{})},async getFiles(){return await this.getUploadedFiles(),Object.entries(this.fileKeyIndex).reduce((e,[t,r])=>(r.error=!1,r.is_success=!0,r.is_new=!1,r.filekey=t,e.push({...r}),e),[])},getUpdateFileEntries:function(){return Object.entries(this.state).map((e,t)=>(delete e.deleted,{key:e}))},dispatchFormEvent:function(e,t={}){this.$el.closest("form")?.dispatchEvent(new CustomEvent(e,{composed:!0,cancelable:!0,detail:t}))},canUpload:function(){return u?Object.entries(this.uploadFiles).length{if(this.state!==void 0){if(this.state!==null&&Object.values(this.state).filter(e=>e.file.startsWith("livewire-file:")).length){this.lastState=null;return}JSON.stringify(this.getUpdateFileEntries())!==this.lastState&&(this.lastState=JSON.stringify(this.getUpdateFileEntries()),this.uploadFiles=await this.getFiles())}}),this.$watch("sortKeys",async()=>{await M(this.sortKeys)}),this.$nextTick(async()=>{this.uploadFiles=await this.getFiles()})},dropcheck:0,usedKeyboard:!1,originalIndexBeingDragged:null,indexBeingDragged:null,indexBeingDraggedOver:null,preDragOrder:null,sortKeys:null,dragstart(e){this.preDragOrder=[...this.uploadFiles],this.indexBeingDragged=e.target.getAttribute("x-ref"),this.originalIndexBeingDragged=e.target.getAttribute("x-ref"),e.dataTransfer.dropEffect="copy"},updateListOrder(e){if(this.indexBeingDragged){this.indexBeingDraggedOver=e.target.getAttribute("x-ref");let t=this.indexBeingDragged,r=this.indexBeingDraggedOver;if(this.indexBeingDragged===r||t===r)return;this.move(t,r),this.indexBeingDragged=r}},setParentDraggable(e){e.target.closest("li").setAttribute("draggable",!0)},setParentNotDraggable(e){e.target.closest("li").setAttribute("draggable",!1)},resetState(){this.dropcheck=0,this.indexBeingDragged=null,this.preDragOrder=[...this.uploadFiles],this.indexBeingDraggedOver=null,this.originalIndexBeingDragged=null},revertState(){this.uploadFiles=this.preDragOrder.length?this.preDragOrder:this.uploadFiles,this.resetState()},rePositionPlaceholder(){this.uploadFiles=[...this.preDragOrder],this.indexBeingDragged=this.originalIndexBeingDragged},move(e,t){let r=this.uploadFiles;if(t>=r.length){let n=t-r.length+1;for(;n--;)r.push(void 0)}r.splice(t,0,r.splice(e,1)[0]),this.uploadFiles=r},getSort(){if(this.indexBeingDragged===this.originalIndexBeingDragged)return null;this.sortKeys=this.uploadFiles.map(e=>e.filekey)}}}export{A as galleryFileUpload};
diff --git a/resources/js/index.js b/resources/js/index.js
index b839235..5566bbc 100644
--- a/resources/js/index.js
+++ b/resources/js/index.js
@@ -78,10 +78,17 @@ export function galleryFileUpload(
/**@type {HTMLElement} */
const wrapper = this.$refs.galleryImages
const stopUploading = function(component) {
- let rest = component.uploadFiles.filter(f => f.is_success === false).length
+ let rest = component.uploadFiles.filter(f => f.is_success === false).length,
+ numberErrors = component.uploadFiles.filter(f => f.error === true).length
- if (rest === 0) {
+ if ((rest - numberErrors) === 0) {
component.dispatchFormEvent('form-processing-finished')
+ if(numberErrors) {
+ // Removed thumbnails with no upload
+ component.uploadFiles = component.uploadFiles
+ .filter(file => !file.error)
+ .map(file =>{ file.error = false; return file })
+ }
component.startUpload = false
}
}
@@ -91,7 +98,6 @@ export function galleryFileUpload(
stopUploading(this)
}
const error = (fileKey) => {
- //delete this.uploadFiles[fileKey]
this.uploadFiles[fileKey].progress = 0
this.uploadFiles[fileKey].error = true
stopUploading(this)
diff --git a/src/JsonMedia/ImageManipulation/Croppa.php b/src/JsonMedia/ImageManipulation/Croppa.php
index 5835603..713a2ac 100644
--- a/src/JsonMedia/ImageManipulation/Croppa.php
+++ b/src/JsonMedia/ImageManipulation/Croppa.php
@@ -9,7 +9,6 @@
use Spatie\Image\Exceptions\InvalidImageDriver;
use Spatie\Image\Exceptions\InvalidManipulation;
use Spatie\Image\Image;
-use Spatie\Image\Manipulations;
final class Croppa
{
@@ -34,28 +33,18 @@ public function url(): string
*/
public function render(): void
{
- $image = Image::load($this->filesystem->path($this->filePath))
- ->useImageDriver(config('gallery-json-media.images.driver'));
-
- $manipulations = new Manipulations();
- $manipulations->quality(config('gallery-json-media.images.quality'));
-
- if ($this->width and $this->height) {
- $manipulations->crop(
- cropMethod: config('gallery-json-media.images.thumbnails-crop-method'),
- width: $this->width,
- height: $this->height
- );
- } else {
- if ($this->width) {
- $manipulations->width($this->width);
- }
- if ($this->height) {
- $manipulations->height($this->height);
- }
+ $image = Image::useImageDriver(config('gallery-json-media.images.driver'))
+ ->load($this->filesystem->path($this->filePath))
+ ->quality(config('gallery-json-media.images.quality'));
+
+ if ($this->width) {
+ $image->width($this->width);
+ }
+ if ($this->height) {
+ $image->height($this->height);
}
- $image->manipulate($manipulations)
- ->save($this->filesystem->path($this->getPathNameForThumbs()));
+
+ $image->save($this->filesystem->path($this->getPathNameForThumbs()));
}
protected function getPathNameForThumbs(): string