A web está evoluindo, e as tecnologias Web3 estão revolucionando as indústrias tradicionais, incluindo streaming de vídeo. Plataformas como Odysee estão liderando a mudança, oferecendo alternativas descentralizadas ao YouTube e Rumble. Da mesma forma, diferentemente de provedores legados como Google Drive e Dropbox, a Sia está transformando o armazenamento de dados, fornecendo uma abordagem focada na privacidade e centrada no usuário.
Junte-se a nós em uma jornada para construir um dApp de streaming de filmes Web3 de ponta usando NextJs, TypeScript, Tailwind CSS e Sia Renterd. Esta série de tutoriais guiará você na criação de um aplicativo descentralizado que aproveita a tecnologia blockchain da Sia para garantir a propriedade e a privacidade dos dados do usuário.
Ao final deste tutorial, você adquirirá experiência para:
Assista ao vídeo de demonstração abaixo para ver o projeto em ação e inscreva-se em nosso canal para mais conteúdo inovador como este!
Para acompanhar, certifique-se de ter as seguintes ferramentas instaladas. A familiaridade com as pilhas também aumentará sua compreensão:
Esta série de três partes abordará:
Se você preferir assistir a todo o processo de desenvolvimento, recomendo assistir a esta playlist , na playlist, tudo o que está escrito aqui e muito mais está capturado nos vídeos.
Dito isso, vamos começar a configurar este projeto.
Começaremos clonando um repositório preparado que inclui o script docker compose do Sia Renterd e os serviços de backend e frontend. Execute os seguintes comandos:
$ git clone https://github.com/Daltonic/sia_vid_tv $ cd sia_vid_tv
Agora, é crucial que mudemos para nossa ramificação inicial neste projeto GitHub recém-clonado e executemos o comando abaixo para concluí-lo.
$ git checkout 01_starter_branch
Em seguida, vamos configurar a variável de ambiente associada para este serviço Renterd. Crie um arquivo .env
na raiz deste projeto e aplique as chaves abaixo:
RENTERD_SEED=<RENTERD_SEED_PHRASE> RENTERD_API_PASSWORD=<YOUR_PREFERED_PASSWORD> RENTERD_LOG_LEVEL=debug RENTERD_LOG_DATABASE_LEVEL=error
Para obter essas chaves de API, você precisará ter o Sia Renterd instalado em sua máquina; assista ao breve vídeo abaixo, que resume tudo.
Gere uma frase semente com o aplicativo Renterd como visto no vídeo acima, e inclua-a dentro da sua variável de ambiente como instruído no vídeo acima. Substitua a senha por algo que você possa lembrar facilmente.
Em seguida, precisamos instalar o Docker baixando-o do site oficial, caso ainda não tenha feito isso. Como alternativa, use uma plataforma online gratuita como o Gitpod ou um VPS para executar uma instância do Docker, se possível. Caso contrário, instale-o no seu computador local.
Por fim, podemos girar um contêiner docker executando o seguinte comando docker na raiz deste projeto. Certifique-se de que o terminal esteja no mesmo local de diretório que este arquivo docker-compose.yml
.
$ docker compose -f "docker-compose.yml" up -d --build
Observe o comando para puxar o contêiner para baixo: $ docker compose -f "docker-compose.yml" down
. Execute isso quando quiser desligar sua instância do Docker (mas não agora).
Se você seguiu as instruções acima corretamente, deverá ver a interface abaixo quando visitar seu navegador em http://localhost:9880
.
Digite sua senha (da sua variável de ambiente) para efetuar login. Em seguida, siga o procedimento de configuração no vídeo abaixo para configurar sua instância do Sia Renterd para uploads, downloads e streaming de arquivos.
O vídeo acima começa na marca de 6:41
minutos, pare na marca de 20:01
, esta parte guiará você visualmente pelo processo de configuração do Renterd.
Observe que o processo de sincronização do blockchain, juntamente com a correspondência do host, leva até 25 min
para ficar pronto, então você terá que ser paciente com todo o processo.
Crie um novo bucket no Renterd chamado vidtv
, onde todos os nossos arquivos para este projeto serão armazenados. Se você executou as instruções acima com sucesso, seu nó Renterd deve estar pronto para upload e download. Veja a imagem abaixo.
Incrível. Neste ponto, nosso serviço Renterd está pronto para começar a receber arquivos, mas precisamos nos comunicar com ele programaticamente.
Vamos encerrar esta primeira parte deste tutorial configurando os pacotes e as variáveis de ambiente para o backend e o frontend.
Configuração do projeto de backend Siga as instruções a seguir para ter os pacotes de serviço de backend instalados e prontos para desenvolvimento posterior.
Navegue até o diretório de backend a partir de uma nova instância de terminal usando os seguintes comandos:
$ cd backend $ yarn install #you can also use npm install $ touch .env #or mannually create it at the root of the backend directory
Em seguida, forneça as seguintes informações nas variáveis de ambiente.
SIA_API_BUCKET=vidtv SIA_API_PASSWORD=<YOUR_PREFERED_PASSWORD> SIA_API_BASE_URL=http://localhost:9880 ORIGIN=http://localhost:9000 PORT=9000
E agora, execute $ yarn build && yarn start
para iniciar o backend e também confirmar se ele está livre de bugs.
Configuração do Projeto Frontend Por fim, execute os seguintes comandos para instalar os pacotes associados ao frontend. Depois, vamos executá-lo.
Navegue até o diretório de backend a partir de uma nova instância de terminal usando os seguintes comandos:
$ cd frontend $ yarn install #you can also use npm install $ touch .env #or mannually create it at the root of the backend directory
Em seguida, forneça as seguintes informações nas variáveis de ambiente.
NEXT_PUBLIC_PROJECT_ID=<YOUR_WALLET_CONNECT_ID> NEXT_PUBLIC_FILE_SERVICE_URL=http://localhost:9000
Cadastre-se e crie um projeto com o Walletconnect para obter seu ID de projeto. Após fornecer o ID do projeto para a variável de ambiente, execute $ yarn build && yarn start
para ativar o backend e também confirmar que ele está livre de qualquer bug.
Neste ponto, você verá a interface abaixo ao visitar o navegador em http://localhost:3000
.
Próximo passo Parabéns por atingir esse marco! Prossiga para a Parte 2 para concluir o desenvolvimento do serviço de backend.
Bem-vindo de volta! Por favor, leia a Parte 1 se ainda não leu. Agora, vamos mergulhar na Parte 2: Construindo o serviço de backend para nossa plataforma de streaming de filmes web3.
Fornecemos um código inicial para o backend, que atualmente exibe uma mensagem de "Boas-vindas" quando você inicia o servidor e visita http://localhost:9000
no seu navegador. Vamos construir sobre essa base.
Atualmente, temos esses códigos no diretório de origem do backend. Deixe-me explicá-los brevemente para você.
Arquivos de utilitários Esta pasta, que pode ser totalmente endereçada a backend/src/utils
contém dois arquivos essenciais: uma função de manipulador de exceções HTTP e uma interface para manipular informações de upload de arquivos.
Este código define uma classe HttpException
personalizada que estende a classe Error
do JavaScript integrada, permitindo a criação de instâncias de erro com códigos de status HTTP e mensagens específicas.
https://gist.github.com/Daltonic/bb37e1d4c5f84bc9c10fcbb8c3e19621
Este código define uma interface FileUpload
que representa um arquivo carregado, especificando suas propriedades, como nome, dados, tamanho, codificação e muito mais, fornecendo uma maneira estruturada de lidar com uploads de arquivos neste aplicativo de backend.
https://gist.github.com/Daltonic/64fb31bf3b19668a17d14f59e087a77e
E então, na pasta raiz backend/src
, temos este arquivo index.ts
que configura um servidor Express.js com CORS e suporte para upload de arquivos, define uma única rota GET que retorna uma mensagem de "Boas-vindas" e manipula erros capturando-os e lançando-os novamente como HttpExceptions personalizadas, e então inicia o servidor na porta 9000, conforme especificado nas variáveis de ambiente.
https://gist.github.com/Daltonic/8d76c3a212681d7bfe89b0792b0e707f
Agora que cobrimos os arquivos principais, vamos criar dois novos arquivos em uma pasta services
, cada um servindo a um propósito distinto em nosso aplicativo.
Na pasta backend/src
, crie uma nova pasta chamada services
neste local, é aqui que criaremos dois serviços:
Vamos criar um arquivo chamado sia.service.ts
na pasta backend/src/services
e seguir os passos abaixo para formular este serviço.
Este código define uma classe SiaService
que inicializa com variáveis de ambiente para configurações da API Sia e uma URL de origem, fornecendo uma base para gerenciar interações com o serviço Sia. Agora, vamos fornecer o restante dos códigos para este serviço.
Enviando arquivos para o Sia Renterd Para enviar arquivos para a Sia Network, precisaremos adicionar esses três métodos à classe: dois serão privados e um será público.
Este código define um método privado generateRandomString
que gera uma string aleatória de um comprimento especificado, composta de letras maiúsculas e minúsculas e números, usando um loop para selecionar caracteres aleatoriamente de uma string predefinida. Usaremos isso para renomear cada arquivo exclusivamente antes de enviar um arquivo para Renterd.
O código acima define um método privado uploadToSiaService
que carrega um arquivo para o Sia Renterd usando o Axios, manipulando o progresso e os erros do upload e retornando a resposta do Axios ou gerando um erro se o upload falhar.
Os endpoints do Renterd estão escritos na documentação da API, que você pode conferir ou assistir ao vídeo abaixo, onde expliquei como funciona a documentação da API do Sia Renterd.
Agora vamos incluir o método público que mais tarde exporemos como um endpoint em nosso aplicativo.
Este código define um método público uploadFile
que carrega um arquivo gerando um identificador exclusivo, salvando o arquivo em um cache local e, em seguida, carregando-o no Sia Renterd, retornando a URL do arquivo e uma mensagem de sucesso ou gerando um erro se o upload falhar.
Baixando arquivos para o Sia Renterd Para baixar arquivos para a Sia Network, precisaremos adicionar esses dois métodos na classe, um será privado e o outro será público.
Este código define um método privado downloadFromSiaService
que recupera um arquivo do serviço Sia, armazena-o em cache localmente e retorna um fluxo legível do arquivo, manipulando erros e retornando uma imagem 404 se o arquivo não for encontrado.
Vamos ter esses response_files disponíveis no diretório backend, senão teremos um erro ao chamar o arquivo 404.png
. No diretório backend
, crie outra pasta chamada response_files
e copie as seguintes imagens para ela.
Perfeito, agora vamos completar esse serviço de download de arquivo. Adicione também o método abaixo na classe SiaService
.
Este código define um método público downloadFile
que chama o método privado downloadFromSiaService
para recuperar um arquivo do Sia Renterd e retorna o fluxo legível do arquivo recuperado.
É hora de acoplar esses vários métodos aos seus respectivos endpoints, atualmente, temos apenas um, mas precisaremos de dois adicionais para upload e download de arquivos. O streaming de arquivos também utilizará o endpoint de download.
Vá até o arquivo backend/src/index.ts
e atualize seu conteúdo com esses códigos.
Este código configura um servidor Express.js com CORS e suporte para upload de arquivos, definindo três pontos de extremidade: uma mensagem de boas-vindas, upload de arquivo para a Sia Network e download de arquivo da Sia Network, usando a classe SiaService para manipular operações de arquivo e HttpException para tratamento de erros.
Assista a esta seção do vídeo abaixo se precisar de algum auxílio visual. Pare no horário 01:50:44 .
Precisamos criar um serviço de gerenciamento de cache para garantir que nosso servidor não fique cheio de arquivos não utilizados, controlando por quanto tempo os arquivos permanecem no cache. É importante saber que a única razão pela qual precisamos desse serviço é para reduzir a latência de dados .
Vá para a pasta backend/src/services
e crie um arquivo chamado background.service.ts
e adicione essas sequências de código a ele.
Este código define uma classe BackgroundService
que configura um diretório de cache e agenda jobs diários usando a biblioteca node-cron
, inicializando os jobs em background e registrando uma mensagem de confirmação. Vamos criar um método que será responsável por excluir arquivos com mais de 7 dias no cache.
Excluindo arquivo antigo Adicione este método à classe BackgroundService
.
Este código define um método chamado deleteOldFiles
que remove arquivos de um diretório de cache com mais de 7 dias, lendo o diretório, verificando o tempo de criação de cada arquivo, removendo arquivos que excedem o tempo alvo, registrando o início e o fim do trabalho e quaisquer erros ou exclusões bem-sucedidas.
Agora, vamos escrever uma função que utilizará o pacote node-cron para agendar quando executar a exclusão do arquivo.
Este código configura uma tarefa cron diária para executar o método deleteOldFiles
todos os dias à meia-noite (00:00) para realizar a limpeza automática de arquivos.
Também precisamos atualizar a função construtora para agendar os trabalhos diários na instanciação da classe de serviço em segundo plano.
Perfeito, por fim, vamos adicionar essa operação em segundo plano como parte do processo do servidor na inicialização. Vá para o arquivo backend/src/index.ts
e atualize o método app listener para importar o arquivo de serviço em segundo plano.
Você deve executar novamente o comando de serviço de backend usando $ yarn build && yarn start
e ver uma impressão de terminal como a da imagem abaixo.
Se você preferir assistir como eu codifiquei todo o serviço em segundo plano, o vídeo abaixo é para você; apenas certifique-se de parar no registro de data e hora 02:16:07 .
Próximo passo Parabéns, agora você está pronto para a parte final deste tutorial, que é a Parte 3 .
Vamos mergulhar na parte final desta série de tutoriais, onde integraremos o backend com o Frontend, conectando as peças para concluir o aplicativo de upload de arquivo. Começaremos garantindo que as autenticações no Frontend estejam ativas e funcionando.
Crie uma nova pasta chamada 'config' no diretório Frontend e adicione um arquivo index, resultando no caminho /frontend/config/index.tsx
. Agora, vamos adicionar os seguintes códigos a ele.
Este código configura uma configuração Wagmi para nosso aplicativo Web3, definindo metadados, cadeias suportadas e configurações de autenticação, incluindo opções de carteira e login social, e armazena-as na exportação config
. Também precisamos criar uma API de contexto para manter o controle do estado de autenticação.
A API de contexto Em seguida, crie uma nova pasta chamada 'context' ainda no diretório Frontend e adicione um arquivo de índice, resultando no caminho /frontend/context/index.tsx
. Adicione os seguintes códigos a ela.
Este código configura um provedor Web3Modal usando Wagmi e React Query, configurando o modal Web3 com o ID do projeto e variáveis de tema e encapsulando o aplicativo em um WagmiProvider e QueryClientProvider.
Atualizando Layout : Vamos atualizar o layout do nosso aplicativo para incluir as configurações acima. Vá para /frontend/app/layout.tsx
e substitua seus códigos pelo abaixo.
O código acima configura o layout raiz para um aplicativo Next.js, incluindo metadados, fontes, estilos e provedores para modal Web3, notificações do sistema e componentes de layout como cabeçalho e rodapé.
O botão de login Agora, precisamos habilitar os botões de login nos componentes /frontend/app/components/layout/Header.tsx
e /frontend/app/components/shared/Menu.tsx
e atualizar seus códigos usando as informações abaixo.
Este código define um componente React para uma barra de navegação que inclui um logotipo, links de navegação, um menu personalizado e um botão de login que inicia um Modal Web3 com um design responsivo para diferentes tamanhos de tela.
As imagens a seguir devem aparecer como prova de que o que fizemos funciona quando você clica no botão de login e prossegue com seu provedor preferido, X, Facebook, Google, Discord ou Ethereum.
Ótimo, vamos nos aprofundar e configurar nosso banco de dados e o sistema baseado em API NextJs. Para qualquer confusão sobre o processo, assista à seção de vídeo abaixo; apenas certifique-se de parar na marca de 02:57:59 .
Primeiro, vamos atualizar o script de configuração do NextJs para endereçar corretamente nossas páginas e endpoints e liberar nossas imagens remotas de avisos e escrutínio.
Este código define um objeto de configuração Next.js que configura reescritas de rotas de API e otimização de imagens, permitindo imagens remotas de qualquer nome de host HTTPS e imagens locais do domínio localhost.
Script de configuração do banco de dados Usaremos SQLite para esta aplicação, mas você está livre para usar uma solução mais robusta, como provedores MYSQL ou NOSQL. Para simplificar, vamos trabalhar com um arquivo simples SQLite.
Crie o caminho do arquivo /frontend/app/api/database.ts
e adicione os códigos abaixo a ele.
Este código configura uma conexão de banco de dados SQLite, define duas funções de API, apiGet
e apiPost
, para executar solicitações GET e POST no banco de dados, com tratamento de erros e execução assíncrona baseada em promessas. Usaremos esses códigos sempre que desejarmos enviar ou recuperar dados do banco de dados.
Script de migração de banco de dados Precisamos criar um arquivo simples de banco de dados e uma tabela para armazenar todo o nosso conteúdo. Crie o caminho do arquivo /frontend/app/api/migrations.ts
e adicione os códigos abaixo a ele.
Este código define uma função de migração de banco de dados que cria uma tabela 'movies' com colunas especificadas se ela não existir, usando SQLite, e registra o resultado da operação. Agora execute o comando abaixo em um terminal apontado para o diretório /frontend
.
$ cd frontend $ npx esrun app/api/migrations.ts
Deve-se notar que esse processo também criará um arquivo plano de banco de dados chamado movies.db
na raiz do diretório frontend. Também adicionamos esse comando ao script package.json, então executar $ yarn migrate
no diretório frontend deve funcionar da mesma forma.
Para assistência visual, assista ao vídeo abaixo, basta pará-lo na marca de 03:10:54 .
Agora, vamos definir alguns endpoints para criar, ler, atualizar e excluir filmes. Usaremos a provisão da API NextJs para fazer esses endpoints.
Criar ponto final do filme Para criar um filme, as informações necessárias incluem o ID do usuário, nome do filme, imagem, URL do vídeo, data de lançamento, gênero, classificação, idioma, duração e descrição do plano de fundo. Crie o caminho do arquivo /frontend/app/api/movies/create/route.ts
e adicione os códigos abaixo a ele.
Este código define um ponto de extremidade para manipular solicitações POST, validar e processar dados de filmes, gerar um slug exclusivo e inserir os dados em um banco de dados usando uma função apiPost enquanto manipula erros e retorna respostas JSON.
Atualizar ponto final do filme Para atualizar um filme, as informações necessárias incluem o ID do usuário, slug e outras informações fornecidas ao criar um filme. Crie o caminho do arquivo /frontend/app/api/movies/update/route.ts
e adicione os códigos abaixo a ele.
Este código define um ponto de extremidade para manipular solicitações POST para atualizar um filme, validar propriedades necessárias e executar uma consulta SQL para atualizar os dados do filme no banco de dados usando a função apiPost.
Excluir ponto final do filme Para excluir um filme, as informações necessárias incluem o ID do usuário e o slug de um filme. Crie o caminho do arquivo /frontend/app/api/movies/delete/route.ts
e adicione os códigos abaixo nele.
Este código define um ponto de extremidade para manipular solicitações POST para excluir um filme, validar as propriedades necessárias (userId e slug) e executar uma consulta SQL para excluir o filme do banco de dados usando a função apiPost.
Todos os filmes Endpoint Os dados opcionais necessários para obter filmes são pageSize e userId, que podem ser passados como parâmetros de consulta para filtrar e paginar os resultados. Crie o caminho do arquivo /frontend/app/api/movies/all/route.ts
e adicione os códigos abaixo a ele.
O código acima define um ponto de extremidade para manipular solicitações GET para recuperar filmes, permitindo filtragem opcional por userId e paginação por pageSize, e retorna os resultados no formato JSON.
Single Movie Endpoint Para recuperar um único filme, os dados necessários são o slug de um filme. Crie o caminho do arquivo /frontend/app/api/movies/[slug]/route.ts
e adicione os códigos abaixo a ele.
Este código define um ponto de extremidade para manipular solicitações GET para recuperar um filme por seu slug, validar o parâmetro slug e executar uma consulta SQL para recuperar os dados do filme do banco de dados usando a função apiGet.
Isso marca todos os endpoints que precisaremos para esta aplicação. Se você precisar de um auxílio visual para entender melhor esses endpoints, assista ao vídeo abaixo, apenas certifique-se de parar no timestamp 03:48:22 .
Nossa tarefa é revisar e atualizar componentes e páginas pré-codificados, explicando o propósito e a funcionalidade de cada um e documentando as alterações que fazemos no código existente. Começaremos criando um serviço para interagir com os endpoints que criamos anteriormente no diretório api
.
Crie o caminho do arquivo /frontend/app/services/api.service.ts
e adicione os códigos abaixo a ele.
Este serviço fornece um conjunto de funções para interagir com um banco de dados de filmes, permitindo que o aplicativo busque filmes, busque um único filme por slug, crie um novo filme, atualize um filme existente, exclua um filme e carregue arquivos usando solicitações de API e tratamento de erros.
Vamos revisar e atualizar as várias páginas associadas ao nosso aplicativo. Você não precisaria mudar muitas coisas, apenas as destacadas aqui.
Criar página de filme
Esta página é um formulário de publicação de filmes que permite aos usuários carregar arquivos de vídeo e imagem, inserir detalhes do filme e enviar o formulário para publicar o filme, com validação e tratamento de erros, usando as bibliotecas React e Wagmi.
Agora, atualize o arquivo encontrado em /frontend/app/pages/create/page.tsx
com os códigos abaixo.
As alterações feitas neste código em comparação ao original são:
createMovie
de api.service
e a usei na função handleSubmit
para criar um novo filme.userId
à chamada da função createMovie
, passando o endereço do usuário do hook useAccount
.handleSubmit
foi atualizada para usar toast.promise
para manipular a promessa retornada por createMovie
.createMovie
na função handleSubmit
.
Essas alterações permitem que o formulário envie dados do filme para a API e crie uma nova entrada de filme, ao mesmo tempo em que manipula erros e exibe uma mensagem de sucesso.
Editar página do filme
Esta página de edição de filmes permite que usuários autorizados atualizem detalhes do filme, carreguem pôsteres e vídeos e salvem alterações, com validação e tratamento de erros, utilizando React, Wagmi e Next.js, projetados especificamente para usuários editarem seus filmes.
Agora, atualize o arquivo encontrado em /frontend/app/pages/movies/edit/[slug]/page.tsx
com os códigos abaixo.
As atualizações feitas no código que são diferentes do original são:
fetchMovie
e updateMovie
de @/app/services/api.service
e as usou no gancho useEffect
e na função handleSubmit
, respectivamente.posters.find()
pela função fetchMovie
para recuperar dados do filme.handleSubmit
foi atualizada para chamar a função updateMovie
com os detalhes atualizados do filme.updateMovie
na função handleSubmit
.
Essas alterações permitem que nosso aplicativo interaja com nossos endpoints de API para recuperar e atualizar dados de filmes, enquanto o código original dependia de nossa matriz posters
locais.
Página inicial
Esta página inicial renderiza o componente de banners, uma lista de filmes (de uma fonte de API ou de uma interface de usuário de carregamento) e opções de assinatura, utilizando React e Next.js, para fornecer uma página de destino envolvente e informativa para os usuários.
Atualize o arquivo encontrado em /frontend/app/pages/page.tsx
com os seguintes códigos.
As alterações que fizemos na página inicial são:
fetchMovies
de ./services/api.service
e a usamos no hook useEffect
para recuperar dados de filmes da nossa API.posters
locais pela chamada de função fetchMovies
, que busca dados da nossa API.await
para aguardar a resolução da promessa retornada por fetchMovies
antes de definir o estado movies
.Essas mudanças ajudam nosso aplicativo a recuperar dados de filmes de nossa API em vez de depender de dados locais, tornando o aplicativo mais dinâmico e orientado a dados.
Página da conta do usuário
Esta página exibe uma lista de filmes postados pelo usuário conectado no momento, com um espaço reservado para esqueleto de carregamento enquanto os dados estão sendo buscados e uma mensagem solicitando que o usuário conecte sua conta, caso ainda não tenha feito isso, utilizando Wagmi e react-loading-skeleton.
Atualize o arquivo encontrado em /frontend/app/pages/account/page.tsx
com os seguintes códigos.
As alterações feitas na página são:
fetchMovies
de @/app/services/api.service
e a usamos no gancho useEffect
para recuperar dados de filmes da nossa API.posters
locais pela chamada de função fetchMovies
, que busca dados da nossa API.address
passado como argumento para a função fetchMovies
para recuperar dados de filmes específicos do usuário.address
antes de renderizar a lista de filmes, pois a função fetchMovies
agora lida com essa lógica.loaded
.
Essas alterações recuperam dados do filme da nossa API, específicos para o usuário conectado, e exibem um esqueleto de carregamento enquanto os dados estão sendo buscados.
Página de detalhes dos filmes
Esta página exibe os detalhes de um único filme, incluindo seu nome, ano de lançamento, classificação, duração, gênero e informações básicas, juntamente com um reprodutor de vídeo e filmes relacionados, e fornece opções para editar ou excluir o filme se o usuário for o proprietário, utilizando Next.js e Wagmi.
Atualize o arquivo encontrado em /frontend/app/pages/movies/[slug]/page.tsx
com os seguintes códigos.
Fizemos algumas mudanças enormes aqui! Aqui está um resumo do que fizemos:
deleteMovie
, fetchMovie
e fetchMovies
de @/app/services/api.service
e as usamos para interagir com nossos endpoints de API.deleteMovie
.toast.promise
para exibir uma notificação ao excluir um filme.posters
foram removidos e substituídos por chamadas de API.handleSubmit
foi atualizada para chamar a função deleteMovie
e manipular a resposta.useEffect
para chamar as funções fetchMovie
e fetchMovies
.
Essas alterações fazem com que nosso aplicativo interaja com nossa API para recuperar e excluir dados de filmes e exibir notificações ao usuário durante o processo de exclusão.
Esta parte do vídeo abaixo mostrará a você na prática como integramos essas páginas com o endpoint, sinta-se à vontade para assistir a essa parte se tiver algum problema. Apenas certifique-se de parar no timestamp 04:57:41 .
Vamos discutir o propósito de cada componente em nossa aplicação. Atualizaremos qualquer componente que precise ser modificado.
Componente de banner
Este componente exibe uma imagem de fundo rotativa de banners de filmes, passando por uma matriz de imagens de filmes a cada 5 segundos, criando um efeito de apresentação de slides simples e automático. O código deste componente pode ser acessado em /frontend/app/components/home/Banner.tsx
.
Componente de pôsteres
Este componente exibe um carrossel interativo e responsivo de pôsteres de filmes usando a biblioteca Swiper, com recursos como reprodução automática, paginação e navegação, exibindo uma lista de filmes passados como prop, com um layout dinâmico que se adapta a diferentes tamanhos de tela. O código deste componente pode ser acessado em /frontend/app/components/home/Posters.tsx
.
Componente de IU do pôster
Este componente exibe um layout de esqueleto de espaço reservado para uma seção de pôsteres de filmes, usando a biblioteca react-loading-skeleton, mostrando um número dinâmico de pôsteres de esqueleto com base na prop "posters", com um design responsivo que se adapta a diferentes tamanhos de tela, indicando um estado de carregamento até que os dados reais dos pôsteres sejam buscados e exibidos. Este código de componente pode ser acessado em /frontend/app/components/home/PosterUI.tsx
.
Componente de Assinaturas
Este componente exibe uma seção de planos de assinatura, mostrando vários planos fictícios com seus detalhes, preços e benefícios. Ele permite que os usuários escolham um plano que atenda às suas necessidades, utilizando um layout de grade responsivo e efeitos de foco interativos para aprimorar a experiência do usuário. Este código de componente pode ser acessado em /frontend/app/components/home/Subscription.tsx
.
Componente de Cabeçalho
Este componente renderiza uma barra de navegação fixa no topo da página, apresentando um logotipo, um menu de navegação com links para várias seções, um botão de alternância de menu para design responsivo e um botão de login, fornecendo uma seção de cabeçalho consistente e acessível em todo o aplicativo. Este código de componente pode ser acessado em /frontend/app/components/layout/Header.tsx
.
Componente de rodapé
Este componente renderiza uma seção de rodapé na parte inferior da página, apresentando o logotipo do aplicativo, uma breve descrição, links de navegação, informações de contato e um crédito mencionando a solução de armazenamento descentralizada fornecida pela Sia Foundation, fornecendo uma seção de rodapé clara e organizada com informações e links relevantes. Este código de componente pode ser acessado em /frontend/app/components/layout/Footer.tsx
.
Componente de menu
Este componente renderiza um botão de alternância de menu responsivo, que, quando clicado, abre ou fecha um menu suspenso contendo links de navegação, permitindo que os usuários acessem várias seções do aplicativo em telas menores enquanto ocultam o menu em telas maiores onde os links de navegação já estão visíveis. Este código de componente pode ser acessado em /frontend/app/components/shared/Menu.tsx
.
Componente de cartão de filme
Este componente exibe um único pôster de filme com um efeito hover, mostrando informações adicionais como o nome do filme, ano de lançamento e resumo de fundo, enquanto também serve como um link para a página de detalhes do filme, utilizando um design responsivo e transições animadas para aprimorar a experiência do usuário. Este código de componente pode ser acessado em /frontend/app/components/shared/MovieCard.tsx
.
Componente carregado
Este componente exibe uma prévia de um arquivo carregado, seja uma imagem ou um vídeo, com uma barra de progresso e um botão de remoção, permitindo que os usuários revisem e excluam o arquivo carregado, ao mesmo tempo em que fornece uma interface visualmente atraente e interativa com animações e efeitos de foco. O código deste componente pode ser acessado em /frontend/app/components/shared/Uploaded.tsx
.
Componente de Upload
Este componente fornece uma interface de usuário para upload de arquivos, especificamente vídeos ou pôsteres, com recursos como arrastar e soltar, validação de tipo de arquivo, limites de tamanho, rastreamento de progresso de upload e notificações de sucesso/erro, utilizando uma combinação de gerenciamento de estado do React, tratamento de eventos e integração de API para lidar com o processo de upload.
Atualize o arquivo encontrado em /frontend/app/components/shared/uploader.tsx
com os seguintes códigos.
As alterações feitas neste componente são:
uploadFile
de api.service
que manipula o upload do arquivo.
Este código atualizado é mais completo e robusto, com funcionalidade real de upload de arquivos, rastreamento de progresso, tratamento de erros e melhor organização de código.
O vídeo abaixo explica o que cada componente faz com mais detalhes. Confira para seu melhor aproveitamento.
E é isso, pessoal, nós completamos esse projeto, e o último passo que precisamos dar é lançar esse projeto no navegador. Execute $ yarn build && yarn start
para ver o projeto ao vivo no navegador.
Se você encontrar algum problema, consulte os seguintes recursos para solução de problemas. Até a próxima, tudo de bom!
Sou um desenvolvedor web3 e fundador da Dapp Mentors , uma empresa que ajuda empresas e indivíduos a construir e lançar aplicativos descentralizados. Tenho mais de 8 anos de experiência na indústria de software e sou apaixonado por usar a tecnologia blockchain para criar aplicativos novos e inovadores. Administro um canal no YouTube chamado Dapp Mentors, onde compartilho tutoriais e dicas sobre desenvolvimento web3 e regularmente posto artigos online sobre as últimas tendências no espaço blockchain.