dfa1234 / ngx-image-compress

Angular library for uploading and compressing images
https://image-library.app
MIT License
86 stars 36 forks source link

uploadFile not resolving promise on PWA, isSafari incorrect value #100

Closed saggio89 closed 1 year ago

saggio89 commented 1 year ago

We have a Cordova Angular Ionic app using this plugin.

We noticed that after selecting an image, it's hit or miss if the uploadFile() function returns on the promise.

Even more odd, if we opened up the Safari inspector from my Macbook and tried to inspect the app, while the inspector is open, the uploadFile() function will never return on the promise.

After investigating we saw in the image-compress.ts file there is a regex that checks if the browser isSafari.

When setting this to be permanently true, the plugin works perfectly on our app.

I think the regex needs to be updated to account for PWAs running on iPhones. Maybe instead of checking for "safari" in the regex, check for AppleWebKit?

Here is the output of my navigator.userAgent for each device:

Safari from MacBook: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.2 Safari/605.1.15 isSafari = true

Safari browser from iPhone: Mozilla/5.0 (iPhone; CPU iPhone OS 16_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.3 Mobile/15E148 Safari/604.1 isSafari = true

Our Ionic APP running on an iPhone: Mozilla/5.0 (iPhone; CPU iPhone OS 16_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 isSafari = false (ONLY WORKS PROPERLY IF THIS IS TRUE)

saggio89 commented 1 year ago

Is there even a purpose for the whole logical switch with isSafari? It looks like the only difference that's doing is adding the file input element to the DOM or not. Wouldn't this work in all scenarios by ALWAYS going the isSafari route?

dfa1234 commented 1 year ago

Thank for the detailed issue explanation. The difference is not adding in DOM or not, it's which web api used. At first we wanted to use Renderer provided by angular only, but because of issues in Safari we went on using native Js for it. I will investigate your case within next week.

dfa1234 commented 1 year ago

@saggio89 if fact I think you can already submit a PR for changing the regex, I think your are right. Let's check AppleWebKit instead. Great idea!

dfa1234 commented 1 year ago

Fixed in this commit https://github.com/dfa1234/ngx-image-compress/commit/e0fe90f158ec1b84becaa40a94480a652899106a

hunterjenkinsenzy commented 1 year ago

Hello @dfa1234! Thank you for putting together such an awesome package!

I also am seeing an issue in my Ionic app. When I run my app on the browser everything works as expected, but when I build to an iPhone / Android the uploadFile() promise never gets hit.

I read through your documentation and it seems like it should work for native iOS / Android because you're using Renderer2, but maybe I'm misunderstanding something. Should this package work natively or is that not supported? If it is supported, I might be doing something wrong and I can send you code snippets to help diagnose.

Thanks in advance!

dfa1234 commented 1 year ago

@hunterjenkinsenzy your welcome. Can you elaborate what do you mean it's not working on iPhone or Android? We have a browser stack account and we tested several real device, with success. Please give us a reproducible scenario (what is the browser and OS you use)

hunterjenkinsenzy commented 1 year ago

Of course!

So I'm using Ionic 6 and Angular 14. In my scenario, Your package works on Chrome and Safari, but it's not working on native iOS / Android.

And when I say "not working" I mean the uploadFile() promise never gets hit. Here's a code snippet. Please see my comment of what is not getting hit.

` import {Component} from '@angular/core'; import {NgxImageCompressService} from 'ngx-image-compress';

@Component({ selector: 'app-root', template: <button (click)="compressFile()">Upload and compress Image <img [src]="imgResultBeforeCompression" ngIf="imgResultBeforeCompression" /> <img [src]="imgResultAfterCompression" ngIf="imgResultAfterCompression" /> , }) export class AppComponent { constructor(private imageCompress: NgxImageCompressService) {}

imgResultBeforeCompression: string = '';
imgResultAfterCompression: string = '';

compressFile() {
    this.imageCompress.uploadFile().then(({image, orientation}) => {
        //****THIS IS NEVER GETTING HIT****
        this.imgResultBeforeCompression = image;
        console.log('Size in bytes of the uploaded image was:', this.imageCompress.byteCount(image));

        this.imageCompress
            .compressFile(image, orientation, 50, 50) // 50% ratio, 50% quality
            .then(compressedImage => {
                this.imgResultAfterCompression = compressedImage;
                console.log('Size in bytes after compression is now:', this.imageCompress.byteCount(compressedImage));
            });
    });
}

} `

I obviously grabbed this example from your docs. In my native iOS app I can click the button "upload and compress image", it prompts the native iOS file opener, but never executes any of the subsequent code.

Is there something obvious I'm missing?

dfa1234 commented 1 year ago

Here you can see it working on a real Iphone 13 (Safari)

Closing awaiting any further explanation

image

dfa1234 commented 1 year ago

Please use the demo website image-library.app