![Search icon](https://hackernoon.imgix.net/search-new.png?w=19&h=19)
网络正在不断发展,Web3 技术正在彻底改变传统行业,包括视频流。Odysee 等平台引领潮流,为 YouTube 和 Rumble 提供去中心化的替代方案。同样,与 Google Drive 和 Dropbox 等传统提供商不同, Sia正在改变数据存储,提供注重隐私和以用户为中心的方法。
加入我们,使用 NextJs、TypeScript、Tailwind CSS 和 Sia Renterd 构建尖端的 Web3 电影流媒体 dApp 。本教程系列将指导您创建一个利用 Sia 的区块链技术来确保用户数据所有权和隐私的去中心化应用程序。
在本教程结束时,您将获得以下专业知识:
观看下面的演示视频来了解项目的实际运行,并订阅我们的频道以获取更多类似的创新内容!
为了继续进行,请确保您已安装以下工具,并且熟悉堆栈也将增强您的理解:
本系列由三部分组成,涵盖:
如果您更喜欢观看整个开发过程, 我建议您观看这个播放列表,在播放列表中,这里写的所有内容以及更多内容都包含在视频中。
话虽如此,让我们开始建立这个项目。
我们首先克隆一个包含 Sia Renterd docker compose 脚本以及后端和前端服务的准备好的存储库。运行以下命令:
$ git clone https://github.com/Daltonic/sia_vid_tv $ cd sia_vid_tv
现在,我们必须切换到这个新克隆的 GitHub 项目的启动分支并运行以下命令来完成该操作。
$ git checkout 01_starter_branch
接下来,让我们为这个 Renterd 服务设置相关的环境变量。在此项目的根目录下创建一个.env
文件并应用以下键:
RENTERD_SEED=<RENTERD_SEED_PHRASE> RENTERD_API_PASSWORD=<YOUR_PREFERED_PASSWORD> RENTERD_LOG_LEVEL=debug RENTERD_LOG_DATABASE_LEVEL=error
要获取这些 API 密钥,您需要在您的机器上安装 Sia Renterd;请观看下面的简短视频,它几乎总结了所有内容。
使用 Renterd 应用程序生成种子短语,如上视频所示,并按照上视频中的说明将其包含在环境变量中。将密码替换为您容易记住的内容。
接下来,如果您还没有安装 Docker,我们需要从官方网站下载它来安装。或者,如果可能的话,使用免费的在线平台(如Gitpod)或 VPS 来运行 Docker 实例。否则,请将其安装在本地计算机上。
最后,我们可以通过在该项目的根目录下运行以下 docker 命令来启动 docker 容器。确保终端与此docker-compose.yml
文件位于同一目录位置。
$ docker compose -f "docker-compose.yml" up -d --build
请注意拉下容器的命令: $ docker compose -f "docker-compose.yml" down
。当您想要关闭 Docker 实例时运行此命令(但不是现在)。
如果您正确执行了上述说明,当您在浏览器上访问http://localhost:9880
时,您应该会看到下面的界面。
输入您的密码(来自您的环境变量)登录。然后,按照下面视频中的配置步骤设置您的 Sia Renterd 实例以进行文件上传、下载和流式传输。
上述视频从6:41
分钟开始,请在20:01
处停止,此部分将直观地指导您完成 Renterd 配置过程。
请注意,区块链同步过程以及主机匹配最多需要25 min
才能准备好,因此您必须耐心等待整个过程。
请在 Renterd 上创建一个名为vidtv
的新存储桶,我们将在此存储此项目的所有文件。如果您已成功执行上述说明,您的 Renterd 节点应已准备好进行上传和下载。参见下图。
太棒了。此时,我们的 Renterd 服务已准备好开始接收文件,但我们需要通过编程与其进行通信。
让我们通过为后端和前端设置包和环境变量来完成本教程的第一部分。
后端项目设置执行以下说明以安装后端服务包并准备进一步开发。
使用以下命令从新的终端实例导航到后端目录:
$ cd backend $ yarn install #you can also use npm install $ touch .env #or mannually create it at the root of the backend directory
接下来,将以下信息提供给环境变量。
SIA_API_BUCKET=vidtv SIA_API_PASSWORD=<YOUR_PREFERED_PASSWORD> SIA_API_BASE_URL=http://localhost:9880 ORIGIN=http://localhost:9000 PORT=9000
现在,运行$ yarn build && yarn start
来启动后端并确认它没有任何错误。
前端项目设置最后,运行以下命令来安装与前端相关的包。之后,我们将运行它。
使用以下命令从新的终端实例导航到后端目录:
$ cd frontend $ yarn install #you can also use npm install $ touch .env #or mannually create it at the root of the backend directory
接下来,将以下信息提供给环境变量。
NEXT_PUBLIC_PROJECT_ID=<YOUR_WALLET_CONNECT_ID> NEXT_PUBLIC_FILE_SERVICE_URL=http://localhost:9000
使用Walletconnect注册并创建项目以获取您的项目 ID。将项目 ID 提供给环境变量后,运行$ yarn build && yarn start
以启动后端并确认它没有任何错误。
此时,当你在浏览器访问http://localhost:3000
时,你将看到下面的界面。
下一步恭喜您达到这一里程碑!继续第 2 部分以完成后端服务开发。
欢迎回来!如果您还没有读过第 1 部分,请通读一下。现在,让我们深入了解第 2 部分:为我们的 web3 电影流媒体平台构建后端服务。
我们提供了后端的起始代码,当您启动服务器并在浏览器中访问http://localhost:9000
它会显示“欢迎”消息。让我们在此基础上进行构建。
目前我们在后端的源码目录中有这些代码。我先简单给大家解释一下。
实用程序文件该文件夹可以完全寻址到backend/src/utils
其中包含两个基本文件:一个 HTTP 异常处理函数和一个用于处理文件上传信息的接口。
此代码定义了一个自定义的HttpException
类,该类扩展了内置的 JavaScript Error
类,允许创建具有特定 HTTP 状态代码和消息的错误实例。
https://gist.github.com/Daltonic/bb37e1d4c5f84bc9c10fcbb8c3e19621
此代码定义了一个代表上传文件的接口FileUpload
,指定其属性,如名称、数据、大小、编码等,提供了一种结构化的方式来处理此后端应用程序中的文件上传。
https://gist.github.com/Daltonic/64fb31bf3b19668a17d14f59e087a77e
然后在backend/src
根文件夹中,我们有这个index.ts
文件,它设置了一个具有 CORS 和文件上传支持的 Express.js 服务器,定义了一个返回“欢迎”消息的单个 GET 路由,并通过捕获并重新抛出错误来处理错误作为自定义 HttpExceptions,然后按照环境变量中指定的端口 9000 上启动服务器。
https://gist.github.com/Daltonic/8d76c3a212681d7bfe89b0792b0e707f
现在我们已经介绍了关键文件,让我们在services
文件夹中创建两个新文件,每个文件在我们的应用程序中都有不同的用途。
在backend/src
文件夹中,在此位置创建一个名为services
新文件夹,我们将在此处创建两个服务:
让我们在backend/src/services
文件夹创建一个名为sia.service.ts
的文件,并按照以下步骤制定该服务。
此代码定义了一个SiaService
类,该类使用 Sia API 设置的环境变量和源 URL 进行初始化,为管理与 Sia 服务的交互提供了基础。现在,让我们提供此服务的其余代码。
将文件上传到 Sia Renterd要将文件上传到 Sia 网络,我们需要将这三种方法添加到类中,其中两种是私有的,一种是公共的。
此代码定义了一个私有方法generateRandomString
,该方法使用循环从预定义字符串中随机选择字符,生成指定长度的随机字符串,由大写字母、小写字母和数字组成。在将文件发送到Renterd之前,我们将使用它来唯一地重命名每个文件。
上述代码定义了一个私有方法uploadToSiaService
,该方法使用 Axios 上传文件到 Sia Renterd,处理上传进度和错误,并在上传失败时返回 Axios 响应或抛出错误。
Renterd 端点写在 API 文档中,您可以查看或观看下面的视频,我在其中解释了 Sia Renterd API 文档。
现在让我们包含公共方法,稍后我们将在我们的应用程序中将其作为端点公开。
这段代码定义了一个公共方法uploadFile
,通过生成唯一标识来上传文件,将文件保存到本地缓存,然后上传到Sia Renterd,返回文件的URL和成功信息,如果上传失败则抛出错误。
将文件下载到 Sia Renterd要将文件下载到 Sia 网络,我们需要将这两种方法添加到类中,一种是私有的,另一种是公共的。
这段代码定义了一个私有方法downloadFromSiaService
,从 Sia 服务中获取一个文件,在本地缓存,并返回该文件的可读流,如果找不到该文件则处理错误并返回 404 图像。
让我们在后端目录中使用这些 response_files,否则我们将在调用404.png
文件时遇到错误。在backend
目录中创建另一个名为response_files
文件夹,并将以下图像复制到其中。
完美,现在我们来完成这个文件下载服务。同样在SiaService
类中添加下面的方法。
这段代码定义了一个公共方法downloadFile
,它调用私有方法downloadFromSiaService
从 Sia Renterd 中检索文件并返回检索到的文件的可读流。
现在是时候将这些不同的方法与它们各自的端点结合起来了,目前我们只有一个端点,但我们需要另外两个用于上传和下载文件。文件流也将利用下载端点。
前往backend/src/index.ts
文件并使用这些代码更新其内容。
此代码设置了一个具有 CORS 和文件上传支持的 Express.js 服务器,定义了三个端点:欢迎消息、将文件上传到 Sia 网络和从 Sia 网络下载文件,使用 SiaService 类处理文件操作和 HttpException 进行错误处理。
如果您需要一些视觉帮助,请观看下面这部分视频,确保您在01:50:44时间戳处停止。
我们需要创建一个缓存管理服务,通过控制文件在缓存中停留的时间,确保我们的服务器不会被未使用的文件填满。重要的是要知道,我们需要这项服务的唯一原因是减少数据延迟。
前往backend/src/services
文件夹并创建一个名为background.service.ts
的文件并将这些代码序列添加到其中。
此代码定义了一个BackgroundService
类,该类设置缓存目录并使用node-cron
库安排每日作业,初始化后台作业并记录确认消息。让我们创建一个方法,负责删除缓存中超过 7 天的文件。
删除旧文件将此方法添加到BackgroundService
类。
此代码定义了一个名为deleteOldFiles
的方法,该方法通过读取目录、检查每个文件的创建时间、删除超过目标时间的文件、记录作业的开始和结束以及任何错误或成功删除,从缓存目录中删除超过 7 天的文件。
现在,让我们编写一个函数,利用 node-cron 包来安排何时执行文件删除。
此代码设置了一个每日 cron 作业,每天午夜 (00:00) 运行deleteOldFiles
方法以执行自动文件清理。
我们还需要更新构造函数,以便在后台服务类实例化时安排日常作业。
完美,最后,让我们在初始化时将此后台操作添加为服务器进程的一部分。转到backend/src/index.ts
文件,并更新应用程序侦听器方法以导入后台服务文件。
您应该使用$ yarn build && yarn start
重新运行后端服务命令,并查看如下图所示的终端打印输出。
如果您想观看我如何编写整个后台服务,下面的视频适合您;只需确保您在02:16:07时间戳处停止即可。
下一步恭喜您,您现在已经准备好学习本教程的最后一部分,即第 3 部分。
让我们深入了解本教程系列的最后一部分,我们将集成后端与前端,连接各个部分以完成文件上传应用程序。我们首先要确保前端的身份验证已启动并正在运行。
在 Frontend 目录下新建一个 config 文件夹,并添加一个 index 文件,路径为/frontend/config/index.tsx
,我们来在其中添加如下代码。
此代码为我们的 Web3 应用程序设置 Wagmi 配置,定义元数据、支持的链和身份验证设置(包括钱包和社交登录选项),并将其存储在config
导出中。我们还需要创建一个上下文 API 来跟踪身份验证状态。
Context API接下来,仍在 Frontend 目录中创建一个名为“context”的新文件夹,并添加一个索引文件,路径为/frontend/context/index.tsx
。在其中添加以下代码。
此代码使用 Wagmi 和 React Query 设置 Web3Modal 提供程序,使用项目 ID 和主题变量配置 Web3 模型,并将应用程序包装在 WagmiProvider 和 QueryClientProvider 中。
更新布局:让我们更新应用程序布局以包含上述配置。前往/frontend/app/layout.tsx
并将其代码替换为下面的代码。
上述代码设置了 Next.js 应用程序的根布局,包括元数据、字体、样式和 Web3 模式的提供程序、Toast 通知以及页眉和页脚等布局组件。
登录按钮现在,我们需要在/frontend/app/components/layout/Header.tsx
和/frontend/app/components/shared/Menu.tsx
组件中启用登录按钮,并使用以下信息更新其代码。
此代码为导航栏定义了一个 React 组件,其中包含徽标、导航链接、自定义菜单和登录按钮,该按钮可启动具有响应式设计的 Web3 Modal,适用于不同的屏幕尺寸。
当您单击登录按钮并继续使用您首选的提供商 X、Facebook、Google、Discord 或 Ethereum 时,以下图像应该会弹出,证明我们所做的工作有效。
太棒了,让我们更深入地设置我们的数据库和基于 NextJs API 的系统。如果您对这个过程有任何疑惑,请观看下面的视频部分;只要确保您在02:57:59处停止即可。
首先,让我们更新 NextJs 配置脚本以正确处理我们的页面和端点,并使我们的远程图像免受警告和审查。
此代码定义了一个 Next.js 配置对象,用于设置 API 路由重写和图像优化,允许来自任何 HTTPS 主机名的远程图像和来自 localhost 域的本地图像。
数据库配置脚本我们将使用 SQLite 来开发此应用程序,但您也可以自由使用更强大的解决方案,例如 MYSQL 或 NOSQL 提供程序。为了简单起见,我们使用 SQLite 平面文件。
创建/frontend/app/api/database.ts
文件路径并向其中添加以下代码。
此代码设置了 SQLite 数据库连接,定义了两个 API 函数apiGet
和apiPost
,用于对数据库执行 GET 和 POST 请求,并具有错误处理和基于承诺的异步执行。每当我们想要从数据库发送或检索数据时,我们都会使用这些代码。
数据库迁移脚本我们需要创建一个数据库平面文件和一个表来保存所有内容。创建/frontend/app/api/migrations.ts
文件路径并将以下代码添加到其中。
此代码定义了一个数据库迁移函数,如果不存在,则使用 SQLite 创建具有指定列的“movies”表,并记录操作结果。现在在指向/frontend
目录的终端中运行以下命令。
$ cd frontend $ npx esrun app/api/migrations.ts
需要注意的是,此过程还将在前端目录的根目录中创建一个名为movies.db
的数据库平面文件。我们还将此命令添加到了 package.json 脚本中,因此在前端目录上运行$ yarn migrate
应该会产生相同的效果。
为了获得视觉帮助,请观看下面的视频,只需在03:10:54标记处停止即可。
现在,让我们定义一些用于创建、读取、更新和删除电影的端点。我们将使用 NextJs API 提供来创建这些端点。
创建电影端点创建电影所需的信息包括用户ID,电影名称,图片,视频URL,发布日期,类型,评分,语言,时长和背景描述。创建/frontend/app/api/movies/create/route.ts
文件路径,并将以下代码添加到其中。
此代码定义了一个端点来处理 POST 请求、验证和处理电影数据、生成唯一的 slug,并使用 apiPost 函数将数据插入数据库,同时处理错误并返回 JSON 响应。
更新电影端点要更新电影,所需的信息包括用户 ID、slug 以及创建电影时提供的其他信息。创建/frontend/app/api/movies/update/route.ts
文件路径并将以下代码添加到其中。
此代码定义了一个端点来处理更新电影的 POST 请求、验证所需的属性以及执行 SQL 查询以使用 apiPost 函数更新数据库中的电影数据。
删除电影端点要删除电影,所需信息包括电影的用户 ID 和 slug。创建/frontend/app/api/movies/delete/route.ts
文件路径并在其中添加以下代码。
此代码定义了一个端点来处理删除电影的 POST 请求、验证所需的属性(userId 和 slug)以及执行 SQL 查询以使用 apiPost 函数从数据库中删除电影。
所有电影端点获取电影所需的可选数据是pageSize和userId,可以将其作为查询参数传递以过滤和分页结果。创建/frontend/app/api/movies/all/route.ts
文件路径并将以下代码添加到其中。
上述代码定义了一个端点来处理检索电影的 GET 请求,允许按 userId 进行可选过滤和按 pageSize 进行分页,并以 JSON 格式返回结果。
单个电影端点要检索单个电影,所需的数据是电影的 slug。创建/frontend/app/api/movies/[slug]/route.ts
文件路径并将以下代码添加到其中。
此代码定义了一个端点来处理 GET 请求,以通过其 slug 检索电影、验证 slug 参数以及执行 SQL 查询以使用 apiGet 函数从数据库中检索电影数据。
这标记了此应用程序所需的所有端点。如果您需要视觉辅助来帮助您更好地理解这些端点,请观看下面的视频,只需确保您在03:48:22时间戳处停止即可。
我们的任务是审查和更新预编码的组件和页面,解释每个组件和页面的用途和功能,并记录我们对现有代码所做的更改。我们将首先创建一个服务,用于与我们之前在api
目录中创建的端点进行交互。
创建/frontend/app/services/api.service.ts
文件路径并向其中添加以下代码。
该服务提供了一组与电影数据库交互的功能,允许应用程序获取电影、通过 slug 获取单个电影、创建新电影、更新现有电影、删除电影以及使用 API 请求上传文件并处理错误。
让我们查看并更新与我们的应用程序相关的各个页面。您不需要更改很多内容,只需更改此处突出显示的内容即可。
创建电影页面
该页面是一个电影发布表单,允许用户上传视频和图像文件,输入电影详细信息,并提交表单以发布电影,并使用 React 和 Wagmi 库进行验证和错误处理。
现在,使用以下代码更新/frontend/app/pages/create/page.tsx
中的文件。
此代码与原始代码相比所做的更改如下:
api.service
导入createMovie
函数,并在handleSubmit
函数中使用它来创建新电影。createMovie
函数调用中添加了userId
参数,从useAccount
钩子传递用户的地址。handleSubmit
函数以使用toast.promise
来处理createMovie
返回的承诺。handleSubmit
函数中为createMovie
函数调用添加了错误处理。
这些更改使表单能够将电影数据提交给 API 并创建新的电影条目,同时处理错误并显示成功消息。
编辑电影页面
该电影编辑页面允许授权用户更新电影详细信息,上传海报和视频并保存更改,并通过验证和错误处理进行,使用专为用户编辑电影设计的 React、Wagmi 和 Next.js。
现在,使用以下代码更新/frontend/app/pages/movies/edit/[slug]/page.tsx
中的文件。
与原版不同的代码升级包括:
@/app/services/api.service
导入fetchMovie
和updateMovie
函数,并分别在useEffect
hook 和handleSubmit
函数中使用它们。fetchMovie
函数替换posters.find()
方法来检索电影数据。handleSubmit
函数以使用更新的电影详细信息调用updateMovie
函数。handleSubmit
函数中为updateMovie
函数调用添加了错误处理。
这些变化使我们的应用程序能够与我们的 API 端点交互以检索和更新电影数据,而原始代码依赖于我们的本地posters
数组。
主页
该主页利用 React 和 Next.js 呈现横幅组件、电影列表(来自 API 源或加载 UI)和订阅选项,为用户提供引人入胜且信息丰富的登录页面。
使用以下代码更新/frontend/app/pages/page.tsx
中的文件。
我们对主页所做的更改是:
./services/api.service
导入fetchMovies
函数并在useEffect
钩子中使用它从我们的 API 中检索电影数据。fetchMovies
函数调用替换了本地posters
数据。await
关键字,以等待fetchMovies
返回的承诺得到解决,然后再设置movies
状态。这些变化帮助我们的应用程序从我们的 API 中检索电影数据,而不是依赖本地数据,从而使应用程序更加动态和数据驱动。
用户帐户页面
该页面显示当前连接的用户发布的电影列表,并在获取数据时显示一个加载骨架占位符,如果用户尚未连接他们的帐户,则显示一条消息提示用户连接他们的帐户,使用 Wagmi 和 react-loading-skeleton。
使用以下代码更新/frontend/app/pages/account/page.tsx
中的文件。
对页面所做的更改如下:
@/app/services/api.service
导入fetchMovies
函数并在useEffect
钩子中使用它从我们的 API 中检索电影数据。fetchMovies
函数调用替换了本地posters
数据,该函数调用从我们的 API 中获取数据。address
作为参数传递给fetchMovies
函数来检索特定于用户的电影数据。address
的条件检查,因为fetchMovies
函数现在可以处理这个逻辑。loaded
状态。
这些更改从我们的 API 中检索特定于连接的用户的电影数据,并在获取数据时显示加载骨架。
电影详情页面
该页面显示单部电影的详细信息,包括其名称、上映年份、评级、时长、类型和背景信息,以及视频播放器和相关电影,并提供使用 Next.js 和 Wagmi 编辑或删除电影的选项(如果用户是所有者)。
使用以下代码更新/frontend/app/pages/movies/[slug]/page.tsx
中的文件。
我们在这里做了一些重大改变!以下是我们所做工作的总结:
@/app/services/api.service
导入deleteMovie
、 fetchMovie
和fetchMovies
函数并使用它们与我们的 API 端点进行交互。deleteMovie
函数实现电影删除功能。toast.promise
在删除电影时显示通知。posters
本地数据并用 API 调用替换。handleSubmit
函数以调用deleteMovie
函数并处理响应。useEffect
钩子以调用fetchMovie
和fetchMovies
函数。
这些变化导致我们的应用程序与我们的 API 交互以检索和删除电影数据并在删除过程中向用户显示通知。
以下视频的这一部分将向您展示我们如何将这些页面与端点集成,如果您遇到任何问题,请随时观看该部分。只需确保您在04:57:41时间戳处停止即可。
让我们讨论一下应用程序中每个组件的用途。我们将更新任何需要修改的组件。
横幅组件
此组件显示电影横幅的旋转背景图像,每 5 秒循环显示一组电影图像,从而创建简单且自动的幻灯片效果。此组件代码可在/frontend/app/components/home/Banner.tsx
处访问。
海报组件
该组件使用 Swiper 库显示响应式、可交互的电影海报轮播,具有自动播放、分页和导航等功能,展示作为 prop 传递的电影列表,并具有可适应不同屏幕尺寸的动态布局。此组件代码可在/frontend/app/components/home/Posters.tsx
中查看。
海报 UI 组件
此组件使用 react-loading-skeleton 库显示电影海报部分的占位符骨架布局,根据“posters”属性显示动态数量的骨架海报,采用自适应不同屏幕尺寸的响应式设计,指示加载状态,直到实际海报数据被提取和显示。此组件代码可在/frontend/app/components/home/PosterUI.tsx
中查看。
订阅组件
此组件显示订阅计划部分,展示各种虚拟计划及其详细信息、价格和优惠。它允许用户选择适合自己需求的计划,利用响应式网格布局和交互式悬停效果来增强用户体验。此组件代码可在/frontend/app/components/home/Subscription.tsx
中查看。
标题组件
此组件在页面顶部呈现一个固定导航栏,其中包含徽标、带有指向各个部分链接的导航菜单、用于响应式设计的菜单切换按钮和登录按钮,从而在整个应用程序中提供一致且可访问的标题部分。此组件代码可在/frontend/app/components/layout/Header.tsx
中查看。
页脚组件
该组件在页面底部呈现页脚部分,其中包含应用程序的徽标、简要说明、导航链接、联系信息以及提及由 Sia Foundation 提供支持的去中心化存储解决方案的信用,提供清晰有序的页脚部分以及相关信息和链接。 可以在/frontend/app/components/layout/Footer.tsx
中评估此组件代码。
菜单组件
此组件呈现一个响应式菜单切换按钮,单击该按钮时,会打开或关闭包含导航链接的下拉菜单,让用户可以在较小的屏幕上访问应用程序的各个部分,同时在导航链接已经可见的大屏幕上隐藏菜单。此组件代码可在/frontend/app/components/shared/Menu.tsx
中查看。
电影卡片组件
此组件显示单部电影的海报,并带有悬停效果,显示其他信息,例如电影名称、上映年份和背景摘要,同时还可作为电影详情页面的链接,利用响应式设计和动画过渡来增强用户体验。此组件代码可在/frontend/app/components/shared/MovieCard.tsx
处查看。
已上传组件
此组件显示已上传文件(图片或视频)的预览,并带有进度条和删除按钮,方便用户查看和删除已上传文件,同时还提供具有动画和悬停效果的美观且可交互的界面。此组件代码可在/frontend/app/components/shared/Uploaded.tsx
中查看。
上传器组件
该组件提供了一个用于上传文件(特别是视频或海报)的用户界面,具有拖放、文件类型验证、大小限制、上传进度跟踪和成功/错误通知等功能,利用 React 状态管理、事件处理和 API 集成的组合来处理上传过程。
使用以下代码更新/frontend/app/components/shared/uploader.tsx
中的文件。
对此组件所做的更改如下:
api.service
的uploadFile
函数,用于处理文件上传。
此更新的代码更加完整和强大,具有实际的文件上传功能、进度跟踪、错误处理和更好的代码组织。
下面的视频更详细地解释了每个组件的作用,请查看以获得更好的理解。
就这样,我们已经完成了这个项目,我们需要采取的最后一步是在浏览器上启动这个项目。运行$ yarn build && yarn start
即可在浏览器上实时查看该项目。
如果您遇到任何问题,请参考以下资源进行故障排除。下次再见,祝一切顺利!
我是一名 web3 开发人员,也是Dapp Mentors的创始人,该公司致力于帮助企业和个人构建和发布去中心化应用程序。我在软件行业拥有超过 8 年的经验,并且热衷于使用区块链技术创建新的创新应用程序。我运营着一个名为 Dapp Mentors 的 YouTube 频道,在那里我分享有关 web3 开发的教程和技巧,并定期在线发布有关区块链领域最新趋势的文章。