web-dev-qa-db-fra.com

vérifier si l'utilisateur a déjà installé PWA sur l'écran d'accueil sur Chrome?

J'essaie de créer un bouton "Ajouter à l'écran d'accueil" sur mon application Web progressive, comme décrit dans documentation de Chrome .

Je suis généralement le modèle prescrit, où j'ai un bouton caché qui s'affiche lorsque l'événement beforeinstallprompt de Chrome se déclenche. Je capture l'événement une fois qu'il se déclenche, puis j'utilise l'événement pour commencer la boîte de dialogue d'installation native une fois que j'ai cliqué sur mon propre bouton d'installation. L'exemple de code est ci-dessous:

let deferredPrompt;

window.addEventListener('beforeinstallprompt', (e) => {
  // Prevent Chrome 67 and earlier from automatically showing the Prompt
  e.preventDefault();
  // Stash the event so it can be triggered later.
  deferredPrompt = e;
  // Update UI notify the user they can add to home screen
  btnAdd.style.display = 'block';
});

btnAdd.addEventListener('click', (e) => {
  // hide our user interface that shows our A2HS button
  btnAdd.style.display = 'none';
  // Show the Prompt
  deferredPrompt.Prompt();
  // Wait for the user to respond to the Prompt
  deferredPrompt.userChoice
    .then((choiceResult) => {
      if (choiceResult.outcome === 'accepted') {
        console.log('User accepted the A2HS Prompt');
      } else {
        console.log('User dismissed the A2HS Prompt');
      }
      deferredPrompt = null;
    });
});

Le problème que je rencontre est que je ne veux pas afficher mon bouton d'installation (btnAdd) si l'utilisateur a déjà installé l'application Web sur son écran d'accueil, et j'ai du mal à comprendre comment pour vérifier ce scénario.

J'espérais modifier le code ci-dessus comme suit:

window.addEventListener('beforeinstallprompt', (e) => {
  // Prevent Chrome 67 and earlier from automatically showing the Prompt
  e.preventDefault();
  // Stash the event so it can be triggered later.
  deferredPrompt = e;

  // If the user has not already installed...
  deferredPrompt.userChoice
    .then(choiceResult => {
      if (choiceResult === undefined) {
        // Update UI notify the user they can add to home screen
        btnAdd.style.display = 'block';
      }
    });
});

Pour que le bouton d'installation ne s'affiche pas si l'utilisateur a déjà installé. Mais cela ne semble pas fonctionner. Il semble que s'ils n'ont pas déjà fait de choix, accéder à userChoice invite simplement l'utilisateur directement avec le dialogue natif.

Je ne sais pas vraiment comment fonctionne le beforeinstallevent, donc ce n'est peut-être même pas une bonne stratégie. Idéalement, j'espérais que cela fonctionnerait quelque chose comme navigator.serviceWorker.ready(), qui renvoie une promesse plutôt que d'utiliser des événements du navigateur pour essayer de déterminer quand les choses sont prêtes.

Dans tous les cas, y a-t-il des idées sur la façon de vérifier que l'utilisateur a installé sur l'écran d'accueil avant de montrer mon propre bouton d'installation de l'écran d'accueil?

Edit: Comme Mathias l'a commenté, la vérification de l'événement avant d'afficher le bouton devrait être suffisante. Je crois que le problème que je rencontrais est le résultat de l'utilisation de localhost, qui semble déclencher continuellement l'événement beforeinstallprompt même après l'installation, ce qui n'est pas le comportement souhaité. L'hébergement du code a résolu le problème.

15
David Scales

Peut-être, n'affichez-vous pas le bouton avant d'avoir intercepté la fenêtre contextuelle automatique?

ou
Dans votre code, vérifiez si la fenêtre est autonome
Si c'est le cas, vous n'avez pas besoin d'afficher le bouton

if (window.matchMedia('(display-mode: standalone)').matches) {  
    // do things here  
    // set a variable to be used when calling something  
    // e.g. call Google Analytics to track standalone use   
}  

Mon exemple de testeur ici
https://a2hs.glitch.me

Code source de mon testeur
https://github.com/ng-chicago/AddToHomeScreen

13
Mathias