Progressive Web Apps: como potencializar seu PWA

1. Olá!

Neste laboratório, você vai pegar um aplicativo da Web e adicionar recursos avançados a ele. Este é o sexto de uma série de codelabs complementares para o workshop de Progressive Web App. O codelab anterior foi Solicitar e medir a instalação. Há mais dois codelabs nesta série.

O que você vai aprender

  • Abrir e salvar arquivos do sistema de arquivos do usuário usando a API File System Access
  • Registre seu PWA instalado como um gerenciador de arquivos com a API File Handling
  • Escolher a tela certa para abrir uma janela usando a API Multi-Screen Window Placement
  • Impedir que uma tela entre em modo de espera usando a API Screen Wake Lock

O que você precisa saber

  • JavaScript

O que é necessário

  • Um navegador compatível com as APIs acima. Para algumas APIs, talvez seja necessário usar um navegador com um teste do desenvolvedor ou de origem ativo para concluir.

2. Começar a configuração

Comece clonando ou fazendo o download do código inicial necessário para concluir este codelab:

Se você clonar o repositório, verifique se está na ramificação pwa05--empowering-your-pwa. O arquivo zip também contém o código dessa ramificação.

Essa base de código exige o Node.js 14 ou versões mais recentes. Quando o código estiver disponível, execute npm ci na linha de comando da pasta do código para instalar todas as dependências necessárias. Em seguida, execute npm start para iniciar o servidor de desenvolvimento do codelab.

O arquivo README.md do código-fonte explica todos os arquivos distribuídos. Além disso, estes são os principais arquivos com que você vai trabalhar ao longo deste codelab:

Arquivos de chave

  • js/lib/actions.js: fornece uma classe base para o menu.

Observação importante sobre arquitetura

Neste codelab, você vai editar js/lib/action.js, que gerencia ações para os diferentes botões no menu do app. É possível acessar qualquer propriedade no construtor do menu inicializado, que vai incluir this.editor para uma instância do editor de texto principal. Dois métodos importantes do editor que você vai usar ao longo deste codelab são:

  • this.editor.setContent(content): define o conteúdo do editor como o argumento de conteúdo fornecido.
  • this.editor.content(): recebe o conteúdo atual do editor.

3. Gerenciar arquivos

Agora é possível abrir, salvar e criar arquivos no computador de um usuário graças à API File System Access. Combinado com a API File Handling, que permite aos usuários abrir arquivos diretamente no PWA, ele pode parecer integrado ao dia a dia dos usuários.

Abrir no app

A primeira ação a ser conectada é a capacidade de abrir um arquivo do sistema de arquivos do usuário no app. Em js/lib/actions.js, no método open da classe Actions, escreva um código que faça o seguinte:

  • Abra um seletor de arquivos que vai usar um arquivo text/markdown com extensões .md ou .markdown
  • Defina o título da página como o nome dos arquivos abertos mais PWA Edit
  • Armazene o gerenciador de arquivos em this.handler
  • Defina o conteúdo do editor como o conteúdo de texto do arquivo.
  • Salve o manipulador no armazenamento de objetos settings no banco de dados settings-store IndexedDB.

Positivo: lembre-se de que os construtores de classe não podem ser funções async, mas podem chamar Promises dentro deles.

Agora que você pode abrir um arquivo e salvar qual arquivo está aberto entre os carregamentos, há mais duas coisas que você precisa fazer: configurar o manipulador novamente quando o app for carregado e cancelar a configuração quando o usuário redefinir o app.

Para fazer isso, no construtor da classe Actions em js/lib/actions.js, faça o seguinte:

  • Abra o banco de dados settings-store.
  • Acessar o manipulador salvo na loja de objetos settings
  • Defina this.handler como o valor recuperado e o título da página como o nome do arquivo do manipulador (mais PWA Edit) se houver um manipulador salvo.

Para redefinir o estado do app (o que pode ser feito com CTRL/CMD+Shift+R), atualize o método reset da classe Actions em js/lib/actions.js para fazer o seguinte:

  • Defina o título do documento como PWA Edit.
  • Defina o conteúdo do editor como uma string vazia.
  • Defina this.handler como null
  • Excluir o manipulador salvo do armazenamento de objetos settings

Abrir do sistema de arquivos do usuário

Agora que você pode abrir um arquivo no seu app, permita que os usuários abram o app com o arquivo deles. Ao se registrar como um gerenciador de arquivos para um dispositivo, o usuário pode abrir arquivos no seu app em qualquer lugar do sistema de arquivos.

Negativo : talvez seja necessário ativar um teste de desenvolvedor ou de origem para que isso funcione. Se você precisar ativar um teste para desenvolvedores, recomendamos que faça isso em uma cópia do Chrome Canary em vez do seu navegador normal. Se você precisar ativar um teste de origem, registre-se normalmente e adicione a tag a index.html.

Para começar, em manifest.json, adicione uma entrada file_handlers que faça o seguinte:

  • Abre às /
  • Aceita text/markdown com extensões de arquivo .md ou .markdown.

Isso vai permitir que os usuários abram arquivos com seu app, mas não vai abrir os arquivos no app. Para fazer isso, na classe Actions em js/lib/actions.js, faça o seguinte:

  • Adicione um consumidor window.launchQueue no construtor, chamando this.open com o manipulador, se houver algum.
  • Atualize this.open para aceitar um gerenciador de inicialização opcional
    • Se ele existir e for uma instância de FileSystemFileHandle, use-o como o manipulador de arquivos da função.
    • Se não aparecer, abra o seletor de arquivos.

Depois de fazer as duas etapas acima, instale o PWA e tente abrir um arquivo com ele no sistema de arquivos.

Salvar um arquivo

Há dois caminhos diferentes para salvar: salvar as mudanças em um arquivo já aberto ou salvar em um novo arquivo. Com a API File System Access, salvar em um novo arquivo é realmente criar um arquivo e receber um manipulador de arquivos de volta. Portanto, para começar, vamos salvar de um manipulador existente.

No método save da classe Actions em js/lib/actions.js, faça o seguinte:

  • Receba o manipulador de this.handler ou, se ele não existir, receba o manipulador salvo do banco de dados.
  • Crie o FileSystemWritableFileStream do manipulador de arquivos.
  • Grave o conteúdo do editor no stream
  • Fechar o stream

Depois de conseguir salvar um arquivo, é hora de implementar a opção "Salvar como". Para fazer isso, no método saveAs da classe Actions em js/lib/actions.js, faça o seguinte:

  • Mostre o seletor de arquivos para salvar, descrevendo-o como um Markdown File e fazendo com que ele aceite arquivos text/markdown com uma extensão .md.
  • Defina this.handler como o manipulador retornado
  • Salve o manipulador no armazenamento de objetos settings.
  • Aguarde a conclusão de this.save para salvar o conteúdo no arquivo recém-criado.

Depois disso, volte ao método save, verifique se o handler existe antes de tentar gravar nele e, se não existir, aguarde a conclusão do this.saveAs.

4. Mostrar uma prévia

Com um editor de Markdown, os usuários querem ver uma prévia da saída renderizada. Usando a API Window Management, você abre uma prévia do conteúdo renderizado na tela principal do usuário.

Antes de começar, crie um arquivo js/preview.js e adicione o seguinte código para que ele mostre uma prévia ao ser carregado:

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);
});

A prévia deve se comportar das seguintes maneiras:

  • Quando um usuário clica no botão de visualização e uma visualização não está aberta, ela precisa ser aberta.
  • Quando um usuário clica no botão de visualização e uma visualização está aberta, ela precisa ser fechada.
  • Quando o usuário fecha ou atualiza o PWA, a prévia é fechada.

Comece editando o método preview na classe Actions em js/lib/actions.js para fazer o seguinte:

  • Receber as telas disponíveis usando a API Window Management
  • Filtre as telas para encontrar a principal
  • Abra uma janela para /preview com o título Markdown preview que ocupa metade da largura disponível e toda a altura disponível da tela principal, posicionada de modo que ocupe toda a metade direita disponível dessa tela. As dimensões disponíveis excluem áreas reservadas da tela, como uma barra de menus, uma barra de ferramentas, um status ou um local do sistema.
  • Salve esta janela aberta em this.previewWindow
  • Na parte de cima do método, verifique se this.previewWindow existe. Se sim, feche a janela e remova this.previewWindow em vez de abrir uma visualização da janela.

Por fim, faça o seguinte no final do construtor da classe Actions em js/lib/actions.js:

  • Fechar this.previewWindow durante o evento beforeunload

5. Foco

Por fim, queremos oferecer aos usuários um modo de escrita sem distrações. Sem distrações não significa apenas não ter a confusão de outros apps, mas também evitar que a tela do usuário entre em modo de espera. Para isso, use a API Screen Wake Lock.

O botão de bloqueio de despertar funciona como o botão de visualização, alternando entre os estados ativado e desativado. Para isso, no método focus da classe Actions em js/lib/actions.js, faça o seguinte:

  • Verifique se o documento tem um elemento em tela cheia
  • Se sim:
    • Sair da tela cheia
    • Se this.wakeLock existir, libere o wake lock e redefina this.wakeLock.
  • Se não estiver:
    • Solicitar um sentinel de bloqueio de despertar e defini-lo como this.wakeLock
    • Solicita que o corpo do documento entre em tela cheia.

6. Parabéns!

Você aprendeu a gerenciar arquivos do sistema e integrar seu PWA a um sistema usando a API File System Access e a API File Handling, abrir janelas em diferentes telas com a API Window Management e evitar que uma tela entre em modo de espera com a API Screen Wake Lock.

O próximo codelab da série é Service Worker Includes.