quasarframework / quasar

Quasar Framework - Build high-performance VueJS user interfaces in record time
https://quasar.dev
MIT License
25.77k stars 3.5k forks source link

Single-tap outside a QDialog or QSelect doesn't work in Cordova iOS app. Have to double-tap. #13619

Closed skmbr closed 1 year ago

skmbr commented 2 years ago

What happened?

The user has to double-tap outside a QDialog to close it when the app is built for cordova/iOS. Single tap doesn't do anything.

What did you expect to happen?

For the QDialog to be closed when a single tap is made outside of it.

Reproduction URL

n/a

How to reproduce?

It's only when it's running through Cordova on iOS, either via build or dev

When trying via dev I stopped quasar dev -m cordova -T ios and ran quasar dev, then went back to the app on the phone without rebuilding.

It then only needed a single tap outside a QDialog to dismiss it. When I ran quasar dev -m cordova -T ios again and returned to the app I need double tap again.

Flavour

Quasar CLI with Webpack (@quasar/cli | @quasar/app-webpack)

Areas

Components (quasar), Cordova Mode

Platforms/Browsers

iOS

Quasar info output

Operating System - Darwin(21.4.0) - darwin/x64
NodeJs - 16.2.0

Global packages
  NPM - 7.13.0
  yarn - 1.22.18
  @quasar/cli - 1.3.0
  @quasar/icongenie - 2.3.3
  cordova - 11.0.0

Important local packages
  quasar - 2.7.1 -- Build high-performance VueJS user interfaces (SPA, PWA, SSR, Mobile and Desktop) in record time
  @quasar/app-webpack - 3.5.3 -- Quasar Framework App CLI with Webpack
  @quasar/extras - 1.14.0 -- Quasar Framework fonts, icons and animations
  eslint-plugin-quasar - Not installed
  vue - 3.2.31 -- The progressive JavaScript framework for building modern web UI.
  vue-router - 4.0.14
  pinia - Not installed
  vuex - 4.0.2 -- state management for Vue.js
  electron - 7.3.3 -- Build cross platform desktop apps with JavaScript, HTML, and CSS
  electron-packager - Not installed
  electron-builder - Not installed
  @babel/core - 7.18.2 -- Babel compiler core.
  webpack - 5.73.0 -- Packs CommonJs/AMD modules for the browser. Allows to split your codebase into multiple bundles, which can be loaded on demand. Support loaders to preprocess files, i.e. json, jsx, es7, css, less, ... and your custom stuff.
  webpack-dev-server - 4.8.1 -- Serves a webpack app. Updates the browser on changes.
  workbox-webpack-plugin - Not installed
  register-service-worker - 1.7.2 -- Script for registering service worker, with hooks
  typescript - 4.5.5 -- TypeScript is a language for application scale JavaScript development
  @capacitor/core - Not installed
  @capacitor/cli - Not installed
  @capacitor/android - Not installed
  @capacitor/ios - Not installed

Quasar App Extensions
  *None installed*

Relevant log output

No response

Additional context

Single tap works as it should on Android, as does single click in Chrome or Safari when I'm developing on Desktop, or even when I access the dev server over the network on iOS Safari.

github-actions[bot] commented 2 years ago

Hi @skmbr! πŸ‘‹

It looks like you provided an invalid or unsupported reproduction URL. Do not use any service other than Codepen, jsFiddle, Codesandbox, and GitHub. Make sure the URL you provided is correct and reachable. You can test it by visiting it in a private tab, another device, etc. Please edit your original post above and provide a valid reproduction URL as explained.

Without a proper reproduction, your issue will have to get closed.

Thank you for your collaboration. πŸ‘

MatthewSH commented 2 years ago

So, I wonder if this has to do with the issue I opened (#11582). Looking at client-entry.js again it looks like fastclick is being imported on iOS Cordova too.

@skmbr do you have access to debug the webview? There is an event listener for fastclick that you could try disabling. I also list that in my issue here:

I tracked this down by using Safari web inspector and disabling event listeners after troubleshooting through everything else.

skmbr commented 2 years ago

Thanks for the reply @MatthewSH

I can remote debug via Safari. I've had a look at the event listeners on the dialog backdrop div and can see fastclick mentioned in the click event, but disabling it didn't seem to help.

Could you give me any more info on how you did it?

I've also tried adding a class="needsclick" in various places but that didn't appear to have any effect either.

skmbr commented 2 years ago

I'm also seeing the same issue with QSelect components... only a double-tap outside will close them under cordova/ios.

A single tap causes the QSelect to lose focus, but I still have to double-tap too to get it to close.

MatthewSH commented 2 years ago

Thanks for the reply @MatthewSH

I can remote debug via Safari. I've had a look at the event listeners on the dialog backdrop div and can see fastclick mentioned in the click event, but disabling it didn't seem to help.

Could you give me any more info on how you did it?

I've also tried adding a class="needsclick" in various places but that didn't appear to have any effect either.

If I recall, I had to disable it on the body tag or q-app div. Start at the very top and work your way down, I'm sorry I don't have more information a the moment. When I had the issue, it was months ago.

skmbr commented 2 years ago

Thanks @MatthewSH

I've tried disabling it on both of those, but it seems to affect everywhere, whatever element you have selected at the time.

I've also tried various variations of the last post on this thread:

https://forum.quasar-framework.org/topic/608/disable-fastclick-on-0-13/4?_=1654556785368&lang=en-GB

but adding it to "boot" rather than plugins and tried import FastClick from '@quasar/fastclick' but nothing has any effect.

If anyone can suggest anything else I might try, or tell me how fastclick might be completely disabled to see if it is the problem, I would be very grateful!

cyhnkckali commented 2 years ago

I am also encountering the same error. So I added a close button to the "q-select" slot

rstoenescu commented 2 years ago

Are you using the recommended WebView or are you relying on the stock Cordova one? Because it makes a huge difference.

skmbr commented 2 years ago

Are you using the recommended WebView or are you relying on the stock Cordova one? Because it makes a huge difference.

I'm on cordova-ios 6.2 so I'm using the built in WKWebView. UIWebView got removed in cordova-ios 6.0. Is that what you mean?

I think the docs here are out of date as the wkwebview plugin is now obsolete: https://quasar.dev/quasar-cli-webpack/developing-cordova-apps/preparation#switching-to-ios-wkwebview

cyhnkckali commented 2 years ago

@rstoenescu Yes, I am using the recommended one. Ionic-Webview

manuel-ch commented 2 years ago

@rstoenescu Same problem here but in the context of a PWA installed on iOS (not cordova/capacitor), so i guess i don't have a chance to configure something like https://quasar.dev/quasar-cli-webpack/developing-cordova-apps/preparation#switching-to-ios-wkwebview.

File input buttons, mapbox-geocoder-control and more suffer from requiring double taps.

Also tried class="needsclick" with no impact.

  1. How can i turn fastclick off?
  2. Is it still needed at all?
  3. thanks for providing Quasar, btw πŸ₯‡
skmbr commented 2 years ago

@rstoenescu I'd also be extremely greatful to know the answers to @manuel-ch 's question.

Could https://github.com/quasarframework/quasar/issues/13653 also be fastclick related?

Would really appreciate any suggestions on solving or working around these issues as I have a release deadline fast approaching and will need to look into building my own dialog and textarea components if there's no official solution on the horizon.

dblythy commented 2 years ago

@skmbr I have a bit of a workaround for this, it's not ideal but seems to work (sorry I still use options API).

<template>
<q-dialog
    v-model="_modelValue"
    transition-show="slide-up"
    transition-hide="slide-down"
    :position="position || 'bottom'"
  >
    <slot/>
  </q-dialog>
</template>

<script>
export default {
  props: ["modelValue", "position"],
  emits: ["update:model-value"],
  computed: {
    _modelValue: {
      get () { return this.modelValue },
      set (value) { this.$emit('update:model-value', value) },
    },
  },
  watch: {
    async _modelValue(newVal) {
      if (newVal) {
        await this.$nextTick();
      }
      const background = document.querySelector('.q-dialog__backdrop');
      if (newVal) {
        background.addEventListener('click', () => this.clicked());
      } else {
        background.removeEventListener('click', () => this.clicked());
      }
    }
  },
  methods: {
    clicked() {
      this._modelValue = false;
    }
  }
}
</script>
mamonnnn commented 2 years ago

I also encounter this breaking issue and this needs a fix ASAP. For the meantime I've created this work around hope this helps @skmbr

openDialog() { this.show_dialog = true;

  this.$nextTick(() => {
    $(".q-dialog__backdrop").on('click', function(event){
      this.show_dialog = false;
      event.stopPropagation();
      event.stopImmediatePropagation();
    }.bind(this));
  });

},

skmbr commented 2 years ago

Thank you @dblythy and @mamonnnn for both of your suggestions. I will give them a go.

I ended up building my own very simple dialog component to use in a few key places in order to get our latest release out, as there's been no "official" input on this issue, but obviously I'd rather not be reinventing the wheel!

Hopefully an official fix will happen at some point 🀞

piperone commented 1 year ago

My app, which is a PWA, suffers from this exact issue on iOS so I don't think it's a Cordova-issue; it seems to manifest itself only when running in a dedicated webview; my PWA has to be added to the home-screen and accesses from there in order for the problem to appear. The problem is clear as day, as you can add https://quasar.dev to the home-screen, access it from there and see the problem in action:

https://user-images.githubusercontent.com/351744/202194893-0d339fad-74be-4765-84e5-3874f6af1731.mov

I've gotten an earful from my end-users because of this πŸ‘Ž I don't know if it's related, but I also have a @dblclick-handler on a q-tab which ends up requiring three taps in order to trigger. That's just crazy. Can we please have someone from the Quasar-team look at this?

skmbr commented 1 year ago

Could we have an update from @rstoenescu or somebody on the Quasar team on whether there are any plans to fix or investigate this issue?

I think it's clear from @piperone's comments above, and @manuel-ch back in June, that this is also happening in PWA's so is more than just a Cordova issue.

I'm currently working on features that use QDialog and it's features quite heavily and It would be very useful to know if there is a possibility of a fix soon before I have to build a load more funtionality from scratch or use more clunky workarounds before I can get another release out.

Any information at all would be appreciated.

pdanpdan commented 1 year ago

I cannot reproduce it on iOS with the so-called pwa (link on home)

skmbr commented 1 year ago

@pdanpdan

I've just tested this myself on an iOS 15.6 iPhone SE and an iOS 16.2 iPhone 11 Pro Max, adding Quasar.dev to the home screen from safari, and going to the page for the QDialog component.

I can reproduce with a quick tap. If I hold the tap for a fraction of a second before lifting my finger then it does sometime register, but a literal "tap" does not.

A quick tap of the same speed registers fine on any other interactive element on the page, such as a link, or the API browser at the top of the page.

A double tap of the same speed also does work to dismiss a dialog, but not a single tap.

If I had to theorise, it almost seems like there is some sort of minimum duration threshold between mousedown and mouseup events that means a normal tap can be too quick.

pdanpdan commented 1 year ago

The same tests here, except 16.2 does not exist (at least not for me) and it's 16.1.1 - and all works as expected. Do you have any accessibility settings? Do you have the original screen of the phone?

skmbr commented 1 year ago

16.2 is developer beta.

Both standard settings, no accessibility options.

Both original screens.

Just tried a 2020 iPad Pro 12.9", also on 16.2 Beta 3. Same issue.

pdanpdan commented 1 year ago

I found how to reproduce - you must disable Request desktop site in safari settings

skmbr commented 1 year ago

Great that you can reproduce it, but I don't have that option enabled on any of my devices.

Would be interested to hear if @piperone or @manuel-ch do?

Hopefully your fix works either way 🀞

pdanpdan commented 1 year ago

You don't have it enabled, but by default it is enabled. That way I found how to disable it for all websites :)

piperone commented 1 year ago

If I'm not mistaken, I believe he's saying that in order to reproduce, the setting he mentions has to be off. I just tested this on my brand spanking new iPad Mini; the "request desktop for all sites"-setting is off by default. With the option on, I can single tap on QDialog backdrops in order to dismiss.

skmbr commented 1 year ago

Ok, cool! πŸ˜€ Either way, sounds like good progress. Thank you!!

manuel-ch commented 1 year ago

Same here, Safari option Request desktop site is turned off by default on my iPhones (cause this option is just for exceptional cases of websites with bad/unwanted responsiveness).

Good to see progress on this issue! πŸ‘

Please remember that we see the same problem with other elements, e.g. ordinary (used for custom file choosers) cause quasar seems to apply fastclick all over.

We've solved this by workaround like this:

  function showFileChooser() {
    fileInput.value.click();

    // installed PWA on iOS needs two click events, as first one seems to just fire touch but not click event
    if('standalone' in window.navigator && window.navigator.standalone) {
      fileInput.value.click();
    }
  }
piperone commented 1 year ago

Here are a couple more instances of the same:

QChecbox, QRadio and QToggle when inside QItem (with tag="label") needs two clicks instead of one.

QSelect when behavior="dialog" has the same issue as QDialog (backdrop needs two clicks).

As I mentioned earlier, a @doubleclick handler on QTab ends up requiring three clicks in order to fire.

manuel-ch commented 1 year ago

Is it still necessary to use fastclick at all? According to https://github.com/ftlabs/fastclick which is the origin of @quasar/fastclick in use, it should not be used anymore...

As of late 2015 most mobile browsers - notably Chrome and Safari - no longer have a 300ms touch delay, so fastclick offers no benefit on newer browsers, and risks introducing bugs into your application. Consider carefully whether you really need to use it. ( https://github.com/ftlabs/fastclick)

rstoenescu commented 1 year ago

Fix will be available in Quasar v2.10.3 and v1.22.3

skmbr commented 1 year ago

Awesome, thank you! :)

Minitosh commented 1 year ago

Hi ! I updated Quasar version of my project to quasar@2.11.4 and i still have the issue on IPhone Devices on any versions (from 8 to 14) but it works on IPad devices on all versions