Primeiras aulas do curso Progressive Web Apps: crie apps offline

Progressive Web Apps: crie apps offline

Conhecendo nossa app: um mural de notas no seu celular ou computador - Conhecendo nossa app: um mural de notas no seu celular ou computador

Olá! Tudo bem? Meu nome é Artur e eu serei o seu instrutor nesse curso de Progressive Web Apps.

Vou introduzir esse assunto para você e mostrar o que significa esse palavrão. O que vamos fazer nada mais é do que uma aplicação que funciona no navegador, mas que parece uma aplicação nativa. Vamos fazê-la funcionar a qualquer momento, não importa se você está conectado com a internet ou não – a app funcionará offline.

Mais para o final, também vamos instalar a aplicação, como se ela fosse uma aplicação nativa. Poderemos clicar no ícone e abri-la normalmente, tanto no desktop quanto no celular. Essa é a ideia do curso.

E como começar? Nossa aplicação será um mural ao qual poderemos adicionar notas. Por exemplo, notas de teste. E será possível personalizar as notas, mudando sua cor.

Esse projeto já está prontinho para usarmos. Trabalharemos em cima do código da aplicação que, praticamente, já está funcionando.

Há apenas um problema: quando recarregamos a página, perdemos tudo.

As informações não são salvas. Precisamos de uma maneira de salvá-las e armazená-las no próprio computador ou celular em que rodarmos a aplicação, de maneira que fiquem acessíveis, mesmo sem internet.

O nosso objetivo é usar a aplicação, sem internet. E, no momento, não é possível usá-la offline. Nossa aplicação final, uma Progressive Web App — ou PWA — funcionará até nos casos mais limitados, nas quais sequer há rede. Desenvolveremos um código para que isso aconteça.

A intenção é que, mesmo sem internet, possamos recarregar a página e continuar com o nosso mural. Até logo!

Conhecendo nossa app: um mural de notas no seu celular ou computador - Iniciando o projeto

Antes de começar, caso queira, no link a seguir, você encontra uma boa parte do projeto pronta.


Quando você descompactar e abrir o arquivo, encontrará tudo organizado em pastas. Há uma para os arquivos .css, uma para as imagens, e uma para os .js, além do único .html, o índex, que é o arquivo principal.

Como o código já está pronto, conseguimos vê-lo no navegador. Mas isso não é tão simples: precisamos procurá-lo na pasta e abrir o HTML na mão.

Até funciona no começo, mas recomendo que tenhamos um servidor de arquivos, para facilitar o acesso ao nosso site em uma URL, como localhost:3000. Se conhecer e gostar de um servidor de arquivos específico, fique à vontade para usá-lo. Caso não tenha, recomendo instalar o Node.js, que permitirá executarmos no terminal, no caso, no bash do Ubuntu — sistema que estou usando. Mas o mesmo se aplica aos demais sistemas.

Para instalar o Node, basta fazer npm install. Nosso objetivo é instalar um módulo globalmente (-g), então instalaremos o servidor http-server, da seguinte forma:

Alura-Azul:ceep-pwa alura$ npm install -g http-server

Ao dar "Enter", todas as dependências serão baixadas, junto ao próprio servidor. Depois, no nosso projeto, quando acessarmos a pasta, navegaremos com cd, passando o local em que salvamos o projeto, no caso:

Alura-Azul:ceep-pwa alura$ cd ~/Documents/art/workspace/ceep-pwa

Ao teclar "Enter", poderemos levantar o servidor executando o comando http-server.

Alura-Azul:ceep-pwa alura$ http-server

Pronto! Após teclar "Enter", estará rodando.

Starting up http-server, serving ./
Available on
  http://127.0.0.1:8080
  http://192.168.88.100:8080
Hit CTRL-C to stop the server

É um servidor simples de instalar e usar, pois exige poucos comandos. E agora, podemos acessar o nosso mural dentro de localhost:8080 — endereço indicado no terminal.

No topo da página, em uma faixa azul, encontra-se o título "Ceep", com fonte em negrito, na cor cinza, à esquerda. No canto direito, há um campo de busca e à direita dele o botão "Linhas". Abaixo, em uma faixa cor cinza escura, há outro campo, no qual está escrito "Digite aqui". Abaixo, o botão "Salvar". Abaixo, o fundo da página em cor cinza um pouco mais clara.

E é isso que precisamos para continuar a fazer o nosso sistema: um servidor rodando com os arquivos disponíveis para trabalharmos agilmente.

Logando o usuário com localStorage - Logando o usuário

Vamos continuar o nosso sistema, que chamaremos de Ceep. Nele, conseguimos criar cartões digitando em um campo.

No topo da página, em uma faixa azul, encontra-se o título "Ceep", com fonte em negrito, na cor cinza, à esquerda. No canto direito, há um campo de busca e à direita dele o botão "Linhas". Abaixo, em uma faixa cor cinza escura, há outro campo, no qual será feito um teste com o texto "Oi". Abaixo, o botão "Salvar". Abaixo, o fundo da página em cor cinza um pouco mais clara.

Ao pressionar "Enter", o cartão fica fixado em um mural.

No topo da página, em uma faixa azul, encontra-se o título "Ceep", com fonte em negrito, na cor cinza, à esquerda. No canto direito, há um campo de busca e à direita dele o botão "Linhas". Abaixo, em uma faixa cor cinza escura, há outro campo, no qual está escrito "Digite aqui". Abaixo, o botão "Salvar". Abaixo, o fundo da página em cor cinza um pouco mais clara, no qual está o cartão retangular criado, que é amarelo e armazena o texto "Oi" com a fonte em preto. No canto superior esquerdo do cartão há opções de excluir, editar e alterar a cor, no caso, para vermelho, azul ou verde.

Parece que está funcionando. Mas há um problema: qualquer pessoa que vier nesse computador, verá esses cartões. E como esse é um computador da Alura, ele é compartilhado por diversos usuários. Assim, outras pessoas podem criar cartões e misturá-los aos que já foram criados por outras pessoas.

Mesmo layout apresentado anteriormente em outras imagens, porém, nessa encontram-se dois cartões, cada um de uma cor e com um texto: um deles é vermelho e apresenta o texto "Oi" enquanto o outro é amarelo e aparesenta o texto "Teste".

Por isso, seria interessante que cada uma tivesse o seu próprio mural, para colocar suas ideias, seus lembretes...

Sendo assim, informaremos ao Ceep que os cartões devem ser separados em murais, de acordo com quem os criou. Por exemplo, os cartões que eu, Artur, criar, devem ser adicionados ao meu mural. Sim, temos um nome para isso: login.

Magicamente, nós temos uma visão de como isso funcionará no futuro.

No topo da página, em uma faixa vermelha, encontra-se o título "Futuro", com fonte em negrito, na cor cinza, à esquerda. No canto direito, há um campo de busca e à direita dele o botão "Linhas". Abaixo, em uma faixa cor cinza escura, há outro campo, no qual está escrito "Digite aqui". Abaixo, o botão "Salvar". Abaixo, o fundo da página em cor cinza um pouco mais clara, no qual encontra-se, no topo, o texto "Quem é você?" e, abaixo, um campo para inserir "nome de usuário", que possui um botão quadrado vermelho com o texto "Ok".

Se tentarmos criar um cartão, aparecerá um aviso que diz "Você não está logado".

Para logar, temos um campo de formulário, no qual basta escrever o seu nome e clicar em "Ok", à direita.

Agora que estamos logados, podemos criar cartões.

E o que isso tem a ver com o funcionamento offline da aplicação? Ao recarregar a página, temos o seguinte:

Ainda estou logado. E isso acontece porque alguém tem que saber que o último usuário da última página foi o Artur. Se fecharmos a aba e abri-la novamente, também continuaremos logados:

Então, de algum jeito, a informação de quem estava logado foi armazenada. Isso faz parte do funcionamento offline. E é isso que vamos conferir agora. Vamos para o código?

Voltando para a aplicação "Ceep" do presente, temos que fazer mudanças que impeçam a adição de cartões, sem antes logar. Assim, temos que analisar onde os cartões são adicionados. Nosso sistema está bem dividido, e cada funcionalidade tem praticamente um arquivo para si. Então, quando o usuário digita o texto de um cartão e clica em "Salvar", ele estará chamando uma função adiciona, dentro de um arquivo chamado Mural.js, que está dentro da pasta "js > mural".

Tudo que for relacionado à adição de cartões passa por aqui, onde temos a função adiciona():

const Mural = (function(_render, Filtro){
    "use strict"
    let cartoes = []
    const render = () => _render({cartoes: cartoes, filtro: Filtro.tagsETexto})
    render()
    Filtro.on("filtrado", render)

    function adiciona(cartao){
        cartoes.push(cartao)
        cartao.on("mudanca.**", render)
        render()
        return true
    }

    return Object.seal({
        adiciona
    })

})(Mural_render, Filtro)

Essa função apresenta cartao como parâmetro, uma lista de cartoes — à qual é feita a adição — e o mural sabe que precisa renderizar quando o cartão tiver alguma mudança. Ou seja, como o próprio nome diz, a função adiciona um cartão à página. Assim, se a adição de cartões é feita somente quando logado, ela exige uma condição para que a função seja executada. Ou seja, todo o conteúdo dentro de adiciona() deve estar dentro de um if().

function adiciona(cartao){
    if(){
        cartoes.push(cartao)
        cartao.on("mudanca.**", render)
        render()
        return true
    }

}

Nesse if() precisamos verificar se o usuário está logado ou não. Portanto, verificaremos um valor que será true ou false. Vamos passar logado:

function adiciona(cartao){
  if(logado){
    cartoes.push(cartao)
    cartao.on("mudanca.**", render)
    render()
    return true
  }

}

Poderíamos já criar a variável logado, logo acima da verificação, mas a funcionalidade de todo o login ficaria dentro do mural. E teríamos que adicionar muitas linhas a um código que já faz a parte dele. É melhor não misturar as coisas e seguir o padrão do projeto, separando a funcionalidade de login em outro arquivo.

No projeto, já existe uma pasta chamada "login". Criaremos dentro dela um arquivo com o nome LoginUsuario.js.

Dentro desse arquivo, criaremos a variável logado. Começaremos determinando que o usuário não está logado, com um false, para testar.

let logado = false

De acordo com a função adiciona(), se o usuário estiver logado, poderá criar um cartão. E se não estiver? Precisamos mostrar um alerta para o usuário, que será "Você não está logado".

function adiciona(cartao){
    if(logado){
        cartoes.push(cartao)
        cartao.on("mudanca.**", render)
        render()
        return true
    } else {
        alert("Você não está logado")

    }

}

Se o código estiver funcionando, já teremos uma variável que o mural conseguirá acessar. Para que isso já funcione na aplicação, precisamos adicionar o novo script na página, no arquivo index.html.

<!-- ... -->

<section class="container login"></section>
<section class="container mural"></section>
<script src="js/lib/jquery.js"></script>
<script src="js/lib/eventemitter2.js"></script>
<script src="js/lib/KeyNoardNavigation.js"></script>
<script src="js/tags/Tags.js"></script>
<script src="js/cabecalho/mudaLayout.js"></script>
<script src="js/cabecalho/busca.js"></script>
<script src="js/filtro/Filtro.js"></script>
<script src="js/mural/render/Mural_render.js"></script>
<script src="js/mural/Mural.js"></script>
<script src="js/mural/cartao/render/Cartao_renderHelpers.js"></script>
<script src="js/mural/cartao/render/CartaoOpcoes_render.js"></script>
<script src="js/mural/cartao/render/CartaoConteudo_render.js"></script>

<!-- ... -->

Como é o arquivo do mural que precisa dessa variável, o novo script precisa constar antes dos de mural e sua source (src) deverá apontar para js/login/LoginUsuario.js.

<!-- ... -->

<script src="js/lib/eventemitter2.js"></script>
<script src="js/lib/KeyNoardNavigation.js"></script>
<script src="js/tags/Tags.js"></script>
<script src="js/cabecalho/mudaLayout.js"></script>
<script src="js/cabecalho/busca.js"></script>
<script src="js/filtro/Filtro.js"></script>

<script src="js/login/LoginUsuario.js"></script>

<script src="js/mural/render/Mural_render.js"></script>
<script src="js/mural/Mural.js"></script>
<script src="js/mural/cartao/render/Cartao_renderHelpers.js"></script>
<script src="js/mural/cartao/render/CartaoOpcoes_render.js"></script>
<script src="js/mural/cartao/render/CartaoConteudo_render.js"></script>

<!-- ... -->

Vamos salvar o arquivo e, na aplicação, recarregaremos a página. Em seguida, tentaremos adicionar um cartão com o texto "Oi". Ao tentar salvar, seremos avisados de que não estamos logados.

Será que é porque a variável é false, ou porque ela nem existe? Podemos testar, voltando ao arquivo LoginUsuario.js e substituindo false por true:

let logado = true

Feito isso, voltaremos à aplicação e tentaremos criar um cartão, digitando "oi" e clicando em "Salvar":

No topo da página, em uma faixa azul, encontra-se o título "Ceep", com fonte em negrito, na cor cinza, à esquerda. No canto direito, há um campo de busca e à direita dele o botão "Linhas". Abaixo, em uma faixa cor cinza escura, há outro campo, no qual está escrito "Digite aqui". Abaixo, o botão "Salvar". Abaixo, o fundo da página em cor cinza um pouco mais clara, no qual está o cartão retangular criado, que é amarelo e armazena o texto "oi" com a fonte em preto.

Está funcionando! A variável é acessada pelo mural. Portanto, manteremos o código do login separado do código do mural, que já está cumprindo a sua função. A variável está definida como true, o que não muda muita coisa na aplicação.

Mas, como sabemos se o usuário está logado? Na aplicação do "Futuro", há um botão de "sair" quando o usuário está logado.

No topo da página, em uma faixa vermelha, encontra-se o título "Futuro", com fonte em negrito, na cor cinza, à esquerda. No canto direito, há um campo de busca e à direita dele o botão "Linhas". Abaixo, em uma faixa cor cinza escura, há outro campo, no qual está escrito "Digite aqui". Abaixo, o botão "Salvar". Abaixo, o fundo da página em cor cinza um pouco mais clara, no qual encontra-se, no topo, o texto "Logado como: artur" e o botão para "sair" à direita.

E, quando clicamos em sair, ele volta ao formulário de login.

No topo da página, em uma faixa vermelha, encontra-se o título "Futuro", com fonte em negrito, na cor cinza, à esquerda. No canto direito, há um campo de busca e à direita dele o botão "Linhas". Abaixo, em uma faixa cor cinza escura, há outro campo, no qual está escrito "Digite aqui". Abaixo, o botão "Salvar". Abaixo, o fundo da página em cor cinza um pouco mais clara, no qual encontra-se, no topo, o texto "Quem é você?" e, abaixo, um campo para inserir "nome de usuário", que possui um botão quadrado vermelho com o texto "Ok".

Precisamos estabelecer essa lógica. Mas se tivéssemos que fazer todo o formulário com o campo de texto e o botão vermelho, o código ficaria muito grande para um só curso e nos desviaríamos da questão do funcionamento offline. Por isso, essa parte visual já está pronta. Só precisaremos aprender a usá-la.

Voltando ao arquivo: se o usuário não estiver logado, precisamos mostrar ao usuário, para que ele faça o login.

let logado = false

O código todo está dentro do arquivo LoginUsuario_render.js, na pasta "login".

Ele é o responsável por criar o formulário, criar o botão de "sair" e pelas demais funções visuais. Para renderizar o formulário, ficaremos no arquivo que criamos, começando com o LoginUsuario_render, avisando se há login ou não com um objeto logado, começando com a propriedade false.

let logado = false

LoginUsuario_render({logado: false})

Se o usuário não está logado, precisamos mostrar o formulário. Mas, antes, precisamos adicionar o LoginUsuario_render ao index.html, junto ao LoginUsuario.

<!-- ... -->

<script src="js/lib/eventemitter2.js"></script>
<script src="js/lib/KeyNoardNavigation.js"></script>
<script src="js/tags/Tags.js"></script>
<script src="js/cabecalho/mudaLayout.js"></script>
<script src="js/cabecalho/busca.js"></script>
<script src="js/filtro/Filtro.js"></script>

<script src="js/login/LoginUsuario_render.js"></script>
<script src="js/login/LoginUsuario.js"></script>

<script src="js/mural/render/Mural_render.js"></script>
<script src="js/mural/Mural.js"></script>
<script src="js/mural/cartao/render/Cartao_renderHelpers.js"></script>
<script src="js/mural/cartao/render/CartaoOpcoes_render.js"></script>
<script src="js/mural/cartao/render/CartaoConteudo_render.js"></script>

<!-- ... -->

Esse padrão de manter a parte visual separada está aplicado ao sistema inteiro. Se você analisar o sistema inteiro, confirmará esse padrão observando os arquivos com _render no final, responsáveis pelo visual.

Ao salvar esse arquivo, vamos atualizar a aplicação e conferir se o formulário aparece.

Layout da página de "Ceep" apresentado anteriormente, com o fomulário para login.

Se digitarmos "artur" no login:

Ele entende que estou logado como Artur. Então, devemos conseguir adicionar um cartão, certo?

Porém, ao tentarmos, ele nos informa que não estamos logados. Mas... acabamos de fazer o login!

O que acontece é o seguinte: quando fazemos o render da variável login como false, não estamos mudando o valor da variável logado. Não chegamos a falar isso, e teremos que ensinar essa etapa para LoginUsuario_render.

Uma das coisas que ele conseguirá receber é se o usuário está logado (onLogin) ou não (onLogout). A outra é o que deve acontece quando o usuário digitar seu nome e clicar no ok. Queremos que a variável logado seja true quando o login acontecer.

let logado = false

LoginUsuario_render({
    logado: false
    ,onLogin: () => logado = true

  })

Essa é a famosa função de callback. Se você não está acostumado com ela e a mexer na página, sugiro outros cursos da Alura que falam mais sobre o assunto. Também há os cursos de Jquery, que ensinam a desenvolver os códigos que são executados nas nossas funções de render.

Falta dizermos o que acontece com a variável se o usuário não estiver logado. Sabemos que logado será false. Assim:

let logado = false

LoginUsuario_render({
    logado: false
    ,onLogin: () => logado = true
    ,onLogout: () => logado = false

  })

Esse código diz que a variável muda de acordo com o que o usuário mudar na página. Vamos testar, voltando à aplicação e recarregando-a? Se tentarmos criar um cartão sem logar, teremos o aviso de que não estamos logados.

Novamente, a aplicação nos avisa que não estamos logados. Se logarmos como Artur e tentarmos criar novamente, conseguiremos.

O nosso sistema de login já está funcionando! Claro, poderíamos acrescentar uma senha para deixá-lo mais seguro, mas para esse sistema o nome já basta.

Sobre o curso Progressive Web Apps: crie apps offline

O curso Progressive Web Apps: crie apps offline possui 229 minutos de vídeos, em um total de 66 atividades. Gostou? Conheça nossos outros cursos de JavaScript em Front-end, ou leia nossos artigos de Front-end.

Matricule-se e comece a estudar com a gente hoje! Conheça outros tópicos abordados durante o curso:

Aprenda JavaScript acessando integralmente esse e outros cursos, comece hoje!

  • 1124 cursos

    Cursos de programação, UX, agilidade, data science, transformação digital, mobile, front-end, marketing e infra.

  • Certificado de participação

    Certificado de que assistiu o curso e finalizou as atividades

  • App para Android e iPhone/iPad

    Estude até mesmo offline através das nossas apps Android e iOS em smartphones e tablets

  • Projeto avaliado pelos instrutores

    Projeto práticos para entrega e avaliação dos professores da Alura com certificado de aprovação diferenciado

  • Acesso à Alura Start

    Cursos de introdução a tecnologia através de games, apps e ciência

  • Acesso à Alura Língua

    Reforço online de inglês e espanhol para aprimorar seu conhecimento

Premium

  • 1124 cursos

    Cursos de programação, UX, agilidade, data science, transformação digital, mobile, front-end, marketing e infra.

  • Certificado de participação

    Certificado de que assistiu o curso e finalizou as atividades

  • App para Android e iPhone/iPad

    Estude até mesmo offline através das nossas apps Android e iOS em smartphones e tablets

  • Projeto avaliado pelos instrutores

    Projeto práticos para entrega e avaliação dos professores da Alura com certificado de aprovação diferenciado

  • Acesso à Alura Start

    Cursos de introdução a tecnologia através de games, apps e ciência

  • Acesso à Alura Língua

    Reforço online de inglês e espanhol para aprimorar seu conhecimento

12X
R$75
à vista R$900
Matricule-se

Premium Plus

  • 1124 cursos

    Cursos de programação, UX, agilidade, data science, transformação digital, mobile, front-end, marketing e infra.

  • Certificado de participação

    Certificado de que assistiu o curso e finalizou as atividades

  • App para Android e iPhone/iPad

    Estude até mesmo offline através das nossas apps Android e iOS em smartphones e tablets

  • Projeto avaliado pelos instrutores

    Projeto práticos para entrega e avaliação dos professores da Alura com certificado de aprovação diferenciado

  • Acesso à Alura Start

    Cursos de introdução a tecnologia através de games, apps e ciência

  • Acesso à Alura Língua

    Reforço online de inglês e espanhol para aprimorar seu conhecimento

12X
R$100
à vista R$1.200
Matricule-se

Max

  • 1124 cursos

    Cursos de programação, UX, agilidade, data science, transformação digital, mobile, front-end, marketing e infra.

  • Certificado de participação

    Certificado de que assistiu o curso e finalizou as atividades

  • App para Android e iPhone/iPad

    Estude até mesmo offline através das nossas apps Android e iOS em smartphones e tablets

  • Projeto avaliado pelos instrutores

    Projeto práticos para entrega e avaliação dos professores da Alura com certificado de aprovação diferenciado

  • Acesso à Alura Start

    Cursos de introdução a tecnologia através de games, apps e ciência

  • Acesso à Alura Língua

    Reforço online de inglês e espanhol para aprimorar seu conhecimento

12X
R$120
à vista R$1.440
Matricule-se
Procurando planos para empresas?
Acesso por 1 ano
Estude 24h/dia onde e quando quiser
Novos cursos toda semana