dfa1234/ngx-image-compress

uploadFile not resolving promise on PWA, isSafari incorrect value

Closed this issue · 9 comments

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)

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?

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.

@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!

Fixed in this commit e0fe90f

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!

@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)

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?

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

Closing awaiting any further explanation

image

Please use the demo website image-library.app