1. Te damos la bienvenida
En este lab, tomarás una aplicación web existente y le agregarás capacidades avanzadas. Este es el sexto de una serie de codelabs complementarios para el taller de apps web progresivas. El codelab anterior fue Mensajes y medición de la instalación. Hay dos codelabs más en esta serie.
Qué aprenderás
- Abrir y guardar archivos del sistema de archivos del usuario con la API de File System Access
- Registra tu AWP instalada como controlador de archivos con la API de File Handling
- Cómo elegir la pantalla correcta para abrir una ventana con la API de Multi-Screen Window Placement
- Cómo evitar que una pantalla entre en suspensión con la API de Screen Wake Lock
Lo que debe saber
- JavaScript
Lo que necesitarás
- Un navegador que admita las APIs anteriores En el caso de algunas APIs, es posible que debas usar un navegador con una prueba para desarrolladores o una prueba de origen activa para completar el proceso.
2. Prepárate
Para comenzar, clona o descarga el código de partida necesario para completar este codelab:
Si clonas el repositorio, asegúrate de estar en la rama pwa05--empowering-your-pwa
. El archivo ZIP también contiene el código de esa rama.
Este código base requiere Node.js 14 o una versión posterior. Una vez que tengas el código disponible, ejecuta npm ci
desde la línea de comandos en la carpeta del código para instalar todas las dependencias que necesitarás. Luego, ejecuta npm start
para iniciar el servidor de desarrollo del codelab.
El archivo README.md
del código fuente proporciona una explicación de todos los archivos distribuidos. Además, los siguientes son los archivos existentes clave con los que trabajarás a lo largo de este codelab:
Archivos de claves
js/lib/actions.js
: Proporciona una clase base para el menú.
Nota arquitectónica importante
A lo largo de este codelab, editarás js/lib/action.js
, que administra las acciones de los diferentes botones del menú de la app. Puedes acceder a cualquier propiedad en el constructor del menú inicializado, que incluirá this.editor
para una instancia del editor de texto principal. A lo largo de este codelab, usarás dos métodos importantes del editor:
this.editor.setContent(content)
: Establece el contenido del editor en el argumento de contenido proporcionado.this.editor.content()
: Obtiene el contenido actual del editor.
3. Administrar archivos
Ahora es posible abrir, guardar y crear archivos nuevos en la computadora de un usuario gracias a la API de File System Access. Si se combina con la API de File Handling, que permite a los usuarios abrir archivos directamente en tu AWP, tu AWP puede sentirse integrada sin problemas en la vida cotidiana de los usuarios.
Cómo abrir desde la app
La primera acción que se debe conectar es la capacidad de abrir un archivo del sistema de archivos del usuario desde la app. En js/lib/actions.js
, en el método open
de la clase Actions
, escribe código que haga lo siguiente:
- Abre un selector de archivos que tomará el archivo
text/markdown
con las extensiones.md
o.markdown
. - Establece el título de la página como el nombre de los archivos abiertos, más
PWA Edit
. - Almacena el controlador de archivos en
this.handler
- Establece el contenido del editor en el contenido de texto del archivo.
- Guarda el controlador en el almacén de objetos
settings
en la base de datos IndexedDBsettings-store
.
Positivo: Recuerda que los constructores de clase no pueden ser funciones async
, pero puedes llamar a Promises dentro de ellos.
Ahora que puedes abrir un archivo y guardar qué archivo está abierto entre cargas, hay dos cosas más que debes hacer: volver a configurar el controlador cuando se carga la app y anular su configuración cuando el usuario restablece la app.
Para lograr lo primero, en el constructor de la clase Actions
en js/lib/actions.js
, haz lo siguiente:
- Abre la base de datos
settings-store
. - Obtén el controlador guardado del almacén de objetos
settings
. - Establece
this.handler
en el valor recuperado y el título de la página en el nombre de archivo del controlador (másPWA Edit
) si hay un controlador guardado.
Para restablecer el estado de la app (lo que se puede lograr con CTRL
/CMD
+ Shift
+ R
), actualiza el método reset
de la clase Actions
en js/lib/actions.js
para hacer lo siguiente:
- Establece el título del documento en
PWA Edit
. - Establece el contenido del editor en una cadena vacía.
- Configura
this.handler
ennull
. - Borra el controlador guardado del almacén de objetos
settings
Abrir desde el sistema de archivos del usuario
Ahora que puedes abrir un archivo desde tu app, debes permitir que los usuarios abran tu app con sus archivos. Registrarse como controlador de archivos para un dispositivo permitirá que un usuario abra archivos en tu app desde cualquier lugar de su sistema de archivos.
Negativo : Es posible que debas habilitar una prueba de origen o para desarrolladores para que esto funcione. Si necesitas habilitar una versión de prueba para desarrolladores, te recomendamos que lo hagas en una copia de Chrome Canary en lugar de tu navegador normal. Si necesitas habilitar una prueba de origen, debes registrarte como de costumbre y agregar la etiqueta a
index.html
.
Para comenzar, en manifest.json
, agrega una entrada file_handlers
que haga lo siguiente:
- Abre:
/
- Se acepta
text/markdown
con extensiones de archivo.md
o.markdown
.
Esto permitirá que los usuarios abran archivos con tu app, pero no los abrirá en ella. Para hacerlo, en la clase Actions
de js/lib/actions.js
, haz lo siguiente:
- Agrega un consumidor de
window.launchQueue
en el constructor y llama athis.open
con el controlador, si hay alguno. - Actualiza
this.open
para que acepte un controlador de inicio opcional- Si existe y es una instancia de
FileSystemFileHandle
, úsala como controlador de archivos para la función. - Si no es así, abre el selector de archivos.
- Si existe y es una instancia de
Después de hacer lo anterior, instala tu PWA y trata de abrir un archivo con ella desde el sistema de archivos.
Cómo guardar un archivo
Hay dos rutas de guardado diferentes que un usuario puede querer tomar: guardar los cambios en un archivo ya abierto o guardar en un archivo nuevo. Con la API de File System Access, guardar en un archivo nuevo es, en realidad, crear un archivo nuevo y obtener un controlador de archivos. Por lo tanto, para comenzar, guardemos desde un controlador existente.
En el método save
de la clase Actions
en js/lib/actions.js
, haz lo siguiente:
- Obtén el controlador de
this.handler
o, si no existe, obtén el controlador guardado de la base de datos. - Crea el
FileSystemWritableFileStream
del controlador de archivos - Escribe el contenido del editor en el flujo
- Cierra la transmisión
Una vez que puedas guardar un archivo, es hora de implementar la función Guardar como. Para ello, en el método saveAs
de la clase Actions
en js/lib/actions.js
, haz lo siguiente:
- Mostrar el selector de archivos de guardado, describirlo como un
Markdown File
y hacer que acepte archivostext/markdown
con una extensión.md
- Configura
this.handler
en el controlador devuelto - Guarda el controlador en el almacén de objetos
settings
. - Espera a que finalice
this.save
para guardar el contenido en el archivo recién creado.
Una vez que lo hayas hecho, vuelve al método save
, verifica si existe el handler
antes de intentar escribir en él y, si no existe, espera a que termine this.saveAs
.
4. Cómo mostrar una vista previa
Con un editor de Markdown, los usuarios quieren ver una vista previa del resultado renderizado. Con la API de Window Management, abrirás una vista previa del contenido renderizado en la pantalla principal del usuario.
Antes de comenzar, crea un archivo js/preview.js
y agrégale el siguiente código para que muestre una vista previa cuando se cargue:
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);
});
La vista previa debería comportarse de las siguientes maneras:
- Cuando un usuario hace clic en el botón de vista previa y no se abre una vista previa, se debe abrir la vista previa.
- Cuando un usuario hace clic en el botón de vista previa y se abre una vista previa, esta debe cerrarse.
- Cuando el usuario cierre o actualice la PWA, la vista previa debería cerrarse.
Comienza por editar el método preview
en la clase Actions
en js/lib/actions.js
para hacer lo siguiente:
- Obtén las pantallas disponibles con la API de Window Management
- Filtra las pantallas para encontrar la principal
- Abre una ventana para
/preview
con el títuloMarkdown preview
que ocupa la mitad del ancho disponible y toda la altura disponible de la pantalla principal, y se posiciona de modo que ocupe toda la mitad derecha disponible de esa pantalla. Las dimensiones disponibles excluyen las áreas reservadas de la pantalla, como la barra de menú, la barra de herramientas, el estado o la ubicación del sistema. - Guarda esta ventana abierta en
this.previewWindow
- En la parte superior del método, verifica si existe
this.previewWindow
y, si es así, cierra la ventana y anulathis.previewWindow
en lugar de abrir una vista previa de la ventana.
Por último, haz lo siguiente al final del constructor de la clase Actions
en js/lib/actions.js
:
- Cerrar
this.previewWindow
durante el evento debeforeunload
5. Enfoque
Por último, queremos ofrecer a los usuarios un modo de escritura sin distracciones. La ausencia de distracciones no solo significa que no hay desorden de otras apps, sino que también evita que la pantalla del usuario se apague. Para ello, usarás la API de Screen Wake Lock.
El botón de bloqueo de activación funcionará igual que el botón de vista previa, alternando entre el estado de activación y desactivación. Para ello, en el método focus
de la clase Actions
en js/lib/actions.js
, haz lo siguiente:
- Comprueba si el documento tiene un elemento de pantalla completa
- Si es así, haz lo siguiente:
- Salir de la pantalla completa
- Si existe
this.wakeLock
, libera el bloqueo de activación y restablecethis.wakeLock
.
- Si no es así, haz lo siguiente:
- Solicita un centinela de bloqueo de activación y configúralo en
this.wakeLock
- Solicita que el cuerpo del documento se muestre en pantalla completa.
- Solicita un centinela de bloqueo de activación y configúralo en
6. ¡Felicitaciones!
Aprendiste a administrar archivos del sistema y a integrar tu PWA con un sistema usando la API de File System Access y la API de File Handling, a abrir ventanas en diferentes pantallas con la API de Window Management y a evitar que una pantalla entre en suspensión con la API de Screen Wake Lock.
El siguiente codelab de la serie es Service Worker Includes.