Git Product home page Git Product logo

cefet-web-starwars's Introduction

Guerras Estelares 🌠

Um página com as intros do melhores filmes ever.

Atividade

Você deve usar a Star Wars API (https://swapi.dev) para poder (a) carregar dinamicamente a lista de filmes e (b) também para exibir o respectivo texto introdutório quando o usuário selecionar um filme.

Exercício 0: "cubar" a API

Dê uma explorada na Star Wars API. Será necessário fazer apenas 1 chamada para pegar todos os filmes.

Além disso, inclua o arquivo starwars.js em index.html como um módulo. Veja como incluir um módulo JS). Ele será o único arquivo incluído no index.html, porque os outros serão import ados dentro dele.

Exercício 1: player de música

Vamos colocar uma música pra tocar (e você sabe qual). Via JavaScript, pôr uma música pra tocar é tão simples quanto:

const musica = new Audio(url)
musica.play()

Você pode fazer isso, ou então usar um music player prontinho, com interface gráfica pronta (veja os arquivos music.js e music-sem-private.js).

Ambos arquivos exportam uma única função que espera receber 2 parâmetros:

  1. Objeto com informações da música
    • URL do áudio: audio/tema-sw.mp3
    • URL da capa: imgs/logo.svg
    • Título: Intro
    • Artista: John Williams
  2. Elemento HTML onde o player será injetado (no caso, document.body)
Por que 2 arquivos...

Ambos arquivos (music.js e music-sem-private.js) fazem a mesma coisa. Contudo, music.js usa uma classe com campos privados, o que pode não funcionar em todos os navegadores.

Caso não funcione no seu, use então o music-sem-private.js, que faz exatamente a mesma coisa exceto que todos os membros e métodos da classe são públicos (e, então, funcionará em qualquer navegador recente).

Exercício 2: preencher lista de filmes

Faça uma requisição Ajax (ajax nos slides) para pegar a lista de filmes e, quando a tiver, preencha a #filmes ul com um li para cada filme (slides sobre como inserir elementos dinamicamente).

Cada li deve ter o texto "Episode ROMANO - TITULO", em que ROMANO é o algarismo romano referente ao número do filme e TITULO é o título.

Para a chamada Ajax, você deve usar o fetch, que retorna uma promessa (fetch nos slides) e pode trabalhar tanto com a promessa diretamente ou por meio de async/await (slides sobre async-await).

A resposta da chamada Ajax com dados sobre os filmes não traz o número do filme em romano. Então, será necessário converter de algarismo decimal para romano. Isso deve ser feito em um módulo roman.js que export essa funcionalidade e seja import em starwars.js.

Convertendo de romano para decimal...

Uma ideia legal aqui é aproveitar o fato de que (a) são poucos filmes, (b) que objetos em JavaScript são dicionários e que (c) é possível acessar suas propriedades se soubermos seu nome em uma string ao usar a notação colchetes (ie, obj[prop]).

Por exemplo, veja como poderíamos fazer pra converter emojis de frutas para nomes de frutas:

function emojiParaNome(emoji) {
   const dados = {
      '🍎': 'Maçã',
      '🍍': 'Abacaxi',
      '🥝': 'Kiwi',
      '🍓': 'Morango'
   }

   // retorna o valor da propriedade cujo
   // nome é o emoji do parâmetro
   return dados[emoji]
}

//...
console.log(`Gosto de ${emojiParaNome(🍎)}`)

Se desejar deixar o título de cada filme alinhado (como na segunda imagem), você pode preencher a string referente ao número romano para que ela tenha no mínimo um comprimento definido.

Como preencher uma string com espaços...

Strings possuem dois métodos interessante: s.padStart(tamanho, caractere) e s.padEnd(tamanho, caractere). Esses métodos repetem o caractere uma quantidade de vezes suficiente para que s tenha pelo menos o tamanho. Caso s.length >= tamanho, nada acontece. Caso contrário, é retornada uma string preenchida com tamanho - s.length caracter no início ou no fim de s.

Exemplo:

let alunos = ['Lestat', 'Rui', 'Adamastor']
alunos = alunos.map(aluno => aluno.padEnd(10, '-'))
// [
//   'Lestat----',
//   'Rui-------',
//   'Adamastor-'
// ]

Exercício 3: mostrar a "intro" ao clicar

Ao clicar em um dos episódios, você deve carregar a introdução do filme em pre.introducao. O texto a ser colocado nesse elemento deve ser composto por:

Episode ROMANO
TITULO

CONTEÚDO

...seguindo essas quebras de linha (e linha em branco). Além de definir o conteúdo de pre.introducao conforme definido, para reiniciar a animação (texto comece a subir novamente), invoque a função de restart-animation.js.

Opcional 4: filmes em ordem numérica

Antes de inserir os elementos referentes a cada filme (as lis), ordene os filmes de acordo com seu número, de forma que o primeiro seja o filme I.

Em JavaScript, vetores possuem o método v.sort(funcaoComparadora). Veja a documentação de v.sort() na MDN.

Opcional 5: fetch com cache no localStorage

Para exercitar a criação de promessas e também Web Storage, você deve criar uma função para substituir o fetch e vamos chamá-lo de friendlyFetch. Ele é amigável porque sempre que faz uma requisição Ajax, salva o resultado (depois do .json()) em cache no localStorage usando a URL requisitada como chave. E antes de delegar para a chamada do fetch original, verifica se já não possui a resposta no cache, evitando sobrecarregar a API de Star Wars. Crie essa função em um módulo friendly-fetch.js.

Lembre-se que o Web Storage salva apenas strings, então você pode precisar serializar um objeto antes de salvar e também dessearializar depois que que recuperar o valor salvo lá. Veja slides sobre JSON.

É possível criar uma promessa diretamente ou por como valor de retorno de uma função async.

Criando uma promessa...
function friendlyFetch(url) {
   const promessaDeRequisicao = new Promise((resolve, reject) => {
      // ...
      // executa algo assíncrono (eg, chama fetch(url))
      // ...
      // eventualmente chama resolve(resultado)
      // e se der erro, chama reject(erro)
   })

   return promessaDeRequisicao
}
Retorno de função async...
async function friendlyFetch(url) {
   // ...
   // executa algo assíncrono (eg, chama fetch(url))
   // possivelmente aguardando o resultado dom await
   // ...
   // retorna o resultado
}

Para lembrar como usar localStorage, veja os slides sobre Web Storage.

FAQ

  1. Como enviar requisições assíncronas (Ajax)?
    1. Usar XMLHttpRequest diretamente
    2. Usar fetch
  2. Como usar o localStorage?

cefet-web-starwars's People

Contributors

fegemo avatar urielbra avatar

Watchers

James Cloos avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.