Progressive Web Apps : optimiser votre PWA

1. Bienvenue

Dans cet atelier, vous allez prendre une application Web existante et y ajouter des fonctionnalités avancées. Il s'agit du sixième d'une série d'ateliers de programmation associés à l'atelier sur les progressive web apps. L'atelier de programmation précédent était Inviter à installer et mesurer l'installation. Il existe deux autres ateliers de programmation dans cette série.

Points abordés

  • Ouvrir et enregistrer des fichiers à partir du système de fichiers de l'utilisateur à l'aide de l'API File System Access
  • Enregistrer votre PWA installée en tant que gestionnaire de fichiers avec l'API File Handling
  • Choisir le bon écran pour ouvrir une fenêtre avec l'API Multi-Screen Window Placement
  • Empêcher la mise en veille d'un écran à l'aide de l'API Screen Wake Lock

À savoir

  • JavaScript

Ce dont vous avez besoin

  • Navigateur compatible avec les API ci-dessus Pour certaines API, vous devrez peut-être utiliser un navigateur avec un essai pour les développeurs ou un essai d'origine actifs.

2. Préparer l'atelier

Commencez par cloner ou télécharger le code de démarrage nécessaire pour effectuer cet atelier de programmation :

Si vous clonez le dépôt, assurez-vous d'être dans la branche pwa05--empowering-your-pwa. Le fichier ZIP contient également le code de cette branche.

Ce code de base nécessite Node.js 14 ou version ultérieure. Une fois le code disponible, exécutez npm ci à partir de la ligne de commande dans le dossier du code afin d'installer toutes les dépendances dont vous aurez besoin. Ensuite, exécutez npm start pour démarrer le serveur de développement de l'atelier de programmation.

Le fichier README.md du code source fournit une explication pour tous les fichiers distribués. De plus, voici les principaux fichiers existants que vous utiliserez tout au long de cet atelier de programmation :

Fichiers clés

  • js/lib/actions.js : fournit une classe de base pour le menu.

Remarque importante sur l'architecture

Tout au long de cet atelier de programmation, vous allez modifier js/lib/action.js, qui gère les actions des différents boutons du menu de l'application. Vous pouvez accéder à n'importe quelle propriété dans le constructeur du menu initialisé, qui inclura this.editor pour une instance de l'éditeur de texte principal. Voici deux méthodes d'éditeur importantes que vous utiliserez tout au long de cet atelier de programmation :

  • this.editor.setContent(content) : définit le contenu de l'éditeur sur l'argument de contenu fourni.
  • this.editor.content() : obtient le contenu actuel de l'éditeur.

3. Gérer les fichiers

Il est désormais possible d'ouvrir, d'enregistrer et de créer des fichiers sur l'ordinateur d'un utilisateur grâce à l'API File System Access. Combinée à l'API File Handling, qui permet aux utilisateurs d'ouvrir des fichiers directement dans votre PWA, votre PWA peut sembler parfaitement intégrée à la vie quotidienne de vos utilisateurs.

Ouvrir depuis l'application

La première action à connecter consiste à pouvoir ouvrir un fichier du système de fichiers de l'utilisateur depuis l'application. Dans js/lib/actions.js, dans la méthode open de la classe Actions, écrivez le code qui effectue les opérations suivantes :

  • Ouvrez un sélecteur de fichiers qui accepte les fichiers text/markdown avec les extensions .md ou .markdown.
  • Définissez le titre de la page sur le nom des fichiers ouverts, plus PWA Edit.
  • Stockez le gestionnaire de fichiers sous this.handler.
  • Définissez le contenu de l'éditeur sur le contenu textuel du fichier.
  • Enregistrez le gestionnaire dans le store d'objets settings de la base de données IndexedDB settings-store.

Positif : n'oubliez pas que les constructeurs de classe ne peuvent pas être des fonctions async, mais vous pouvez appeler des promesses à l'intérieur.

Maintenant que vous pouvez ouvrir un fichier et enregistrer le fichier ouvert entre les chargements, il vous reste deux choses à faire : reconfigurer le gestionnaire lorsque l'application se charge et le désactiver lorsque l'utilisateur réinitialise l'application.

Pour ce faire, dans le constructeur de la classe Actions dans js/lib/actions.js, procédez comme suit :

  • Ouvrez la base de données settings-store.
  • Obtenir le gestionnaire enregistré à partir du magasin d'objets settings
  • Définissez this.handler sur la valeur récupérée et le titre de la page sur le nom de fichier du gestionnaire (plus PWA Edit) si un gestionnaire est enregistré.

Pour réinitialiser l'état de l'application (ce qui peut être fait avec CTRL/CMD+Shift+R), mettez à jour la méthode reset de la classe Actions dans js/lib/actions.js pour effectuer les opérations suivantes :

  • Définissez le titre du document sur PWA Edit
  • Définissez le contenu de l'éditeur sur une chaîne vide.
  • Définissez this.handler sur null
  • Supprimer le gestionnaire enregistré du magasin d'objets settings

Ouvrir à partir du système de fichiers de l'utilisateur

Maintenant que vous pouvez ouvrir un fichier depuis votre application, vous devez permettre aux utilisateurs d'ouvrir votre application avec leur fichier. En vous enregistrant en tant que gestionnaire de fichiers pour un appareil, vous permettez à un utilisateur d'ouvrir des fichiers dans votre application depuis n'importe quel emplacement de son système de fichiers.

Négatif : vous devrez peut-être activer un essai du développeur ou Origin pour que cela fonctionne. Si vous devez activer un essai pour les développeurs, nous vous recommandons de le faire dans une copie de Chrome Canary plutôt que dans votre navigateur habituel. Si vous devez activer un Origin Trial, vous devez vous y inscrire normalement et ajouter le tag à index.html.

Pour commencer, dans manifest.json, ajoutez une entrée file_handlers qui effectue les opérations suivantes :

  • Ouverture : /
  • Accepte text/markdown avec les extensions de fichier .md ou .markdown.

Cela permettra aux utilisateurs d'ouvrir des fichiers avec votre application, mais ne les ouvrira pas réellement dans votre application. Pour ce faire, dans la classe Actions de js/lib/actions.js, procédez comme suit :

  • Ajoutez un consommateur window.launchQueue dans le constructeur, en appelant this.open avec le gestionnaire, le cas échéant.
  • Mise à jour de this.open pour accepter un gestionnaire de lancement facultatif
    • S'il existe et qu'il s'agit d'une instance de FileSystemFileHandle, utilisez-le comme gestionnaire de fichiers pour la fonction.
    • Si ce n'est pas le cas, ouvrez le sélecteur de fichier.

Après avoir effectué les deux opérations ci-dessus, installez votre PWA et essayez d'ouvrir un fichier avec elle à partir du système de fichiers.

Enregistrer un fichier

Un utilisateur peut choisir d'enregistrer les modifications apportées à un fichier déjà ouvert ou d'enregistrer un nouveau fichier. Avec l'API File System Access, enregistrer dans un nouveau fichier revient à créer un fichier et à récupérer un gestionnaire de fichiers. Pour commencer, enregistrons à partir d'un gestionnaire existant.

Dans la méthode save de la classe Actions dans js/lib/actions.js, procédez comme suit :

  • Obtenir le gestionnaire à partir de this.handler ou, si cela n'existe pas, obtenir le gestionnaire enregistré à partir de la base de données
  • Créez le FileSystemWritableFileStream du gestionnaire de fichiers.
  • Écrire le contenu de l'éditeur dans le flux
  • Fermer le flux

Une fois que vous pouvez enregistrer un fichier, il est temps d'implémenter l'option "Enregistrer sous". Pour ce faire, dans la méthode saveAs de la classe Actions dans js/lib/actions.js, procédez comme suit :

  • Afficher le sélecteur de fichier d'enregistrement, en le décrivant comme un Markdown File et en lui demandant d'accepter les fichiers text/markdown avec l'extension .md
  • Définissez this.handler sur le gestionnaire renvoyé.
  • Enregistrer le gestionnaire dans le store d'objets settings
  • Attendez que this.save ait terminé pour enregistrer le contenu dans le fichier que vous venez de créer.

Une fois que vous avez fait cela, revenez à la méthode save, vérifiez si handler existe avant d'essayer d'y écrire et, si ce n'est pas le cas, attendez plutôt que this.saveAs se termine.

4. Afficher un aperçu

Avec un éditeur Markdown, les utilisateurs souhaitent voir un aperçu du rendu. À l'aide de l'API Window Management, vous ouvrirez un aperçu du contenu affiché sur l'écran principal de l'utilisateur.

Avant de commencer, créez un fichier js/preview.js et ajoutez-y le code suivant pour afficher un aperçu lors du chargement :

import { openDB } from 'idb';
import { marked } from 'marked';

window.addEventListener('DOMContentLoaded', async () => {
  const preview = document.querySelector('.preview');
  const db = await openDB('settings-store');
  const content = (await db.get('settings', 'content')) || '';

  preview.innerHTML = marked(content);
});

L'aperçu doit se comporter de la manière suivante :

  • Lorsqu'un utilisateur clique sur le bouton d'aperçu et qu'aucun aperçu n'est ouvert, l'aperçu doit s'ouvrir.
  • Lorsqu'un utilisateur clique sur le bouton d'aperçu et qu'un aperçu est ouvert, celui-ci doit se fermer.
  • Lorsque l'utilisateur ferme ou actualise la PWA, l'aperçu doit se fermer.

En commençant par le début, modifiez la méthode preview dans la classe Actions de js/lib/actions.js pour effectuer les opérations suivantes :

  • Obtenir les écrans disponibles à l'aide de l'API Window Management
  • Filtrer les écrans pour trouver l'écran principal
  • Ouvrez une fenêtre pour /preview avec le titre Markdown preview, qui occupe la moitié de la largeur disponible et toute la hauteur disponible de l'écran principal, positionnée de manière à occuper toute la moitié droite disponible de cet écran. Les dimensions disponibles excluent les zones réservées de l'écran, telles que la barre de menu, la barre d'outils, la barre d'état ou la barre de localisation du système.
  • Enregistrer cette fenêtre ouverte dans this.previewWindow
  • En haut de la méthode, vérifiez si this.previewWindow existe. Si c'est le cas, fermez la fenêtre et désactivez this.previewWindow au lieu d'ouvrir un aperçu de la fenêtre.

Enfin, effectuez les opérations suivantes à la fin du constructeur de la classe Actions dans js/lib/actions.js :

  • Fermer this.previewWindow pendant l'événement beforeunload

5. Concentration

Enfin, nous souhaitons offrir aux utilisateurs un mode d'écriture sans distraction. L'absence de distraction ne signifie pas seulement qu'il n'y a pas d'encombrement d'autres applications, mais aussi que l'écran de l'utilisateur ne se met pas en veille. Pour ce faire, vous utiliserez l'API Screen Wake Lock.

Le bouton de verrouillage de l'activation fonctionne comme le bouton d'aperçu, en basculant entre les états "activé" et "désactivé". Pour ce faire, dans la méthode focus de la classe Actions dans js/lib/actions.js, procédez comme suit :

  • Vérifier si le document comporte un élément en plein écran
  • Si c'est le cas :
    • Quitter le mode plein écran
    • Si this.wakeLock existe, libérez le wakelock et réinitialisez this.wakeLock
  • Si ce n'est pas le cas :
    • Demander un sentinel de verrouillage de réveil et le définir sur this.wakeLock
    • Demande à ce que le corps du document passe en plein écran.

6. Félicitations !

Vous avez appris à gérer les fichiers système et à intégrer votre PWA à un système à l'aide de l'API File System Access et de l'API File Handling, à ouvrir des fenêtres sur différents écrans avec l'API Window Management et à empêcher un écran de se mettre en veille avec l'API Screen Wake Lock.

Le prochain atelier de programmation de la série est Service Worker Includes.