ウェブは進化しており、Web3 テクノロジーはビデオストリーミングを含む従来の業界に革命を起こしています。Odysee などのプラットフォームは、YouTube や Rumble に代わる分散型の選択肢を提供することで、その先頭に立っています。同様に、Google Drive や Dropbox などの従来のプロバイダーとは異なり、 Siaはデータ ストレージを変革し、プライバシー重視でユーザー中心のアプローチを提供しています。
NextJs、TypeScript、Tailwind CSS、Sia Renterd を使用して最先端の Web3 映画ストリーミング dApp を構築する旅にご参加ください。このチュートリアル シリーズでは、Sia のブロックチェーン テクノロジーを活用してユーザー データの所有権とプライバシーを確保する分散型アプリケーションの作成方法を説明します。
このチュートリアルを終了すると、次の専門知識を習得できます。
プロジェクトの実際の動作を確認するには、以下のデモ ビデオをご覧ください。また、このような革新的なコンテンツをもっとご覧になりたい場合は、当社のチャンネルに登録してください。
この手順を実行するには、次のツールがインストールされていることを確認してください。また、スタックに精通していると理解も深まります。
この 3 部構成のシリーズでは、次の内容を取り上げます。
開発プロセス全体を視聴したい場合は、 このプレイリストを視聴することをお勧めします。プレイリストでは、ここに書かれていることすべてとそれ以上のことがビデオに収録されています。
それでは、このプロジェクトの設定に取り掛かりましょう。
まず、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 アプリケーションでシード フレーズを生成し、上記のビデオの指示に従ってそれを環境変数内に含めます。パスワードは、簡単に覚えられるものに置き換えます。
次に、まだインストールしていない場合は、公式 Web サイトから 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 20:01
で停止してください。この部分では、Renterd の構成プロセスを視覚的にガイドします。
ブロックチェーンの同期プロセスとホストのマッチングは準備に最大25 min
かかるため、プロセス全体に忍耐が必要になることに注意してください。
Renterd にvidtv
という新しいバケットを作成してください。このバケットにこのプロジェクトのすべてのファイルが保存されます。上記の手順を正常に実行した場合、Renterd ノードはアップロードとダウンロードの準備が整っているはずです。下の画像を参照してください。
素晴らしいですね。この時点で、Renterd サービスはファイルの受信を開始する準備ができていますが、プログラムで通信する必要があります。
バックエンドとフロントエンドのパッケージと環境変数を設定して、このチュートリアルのパート 1 を締めくくりましょう。
バックエンド プロジェクトのセットアップバックエンド サービス パッケージをインストールし、さらなる開発の準備を整えるには、次の手順を実行します。
次のコマンドを使用して、新しいターミナル インスタンスからバックエンド ディレクトリに移動します。
$ 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
プロジェクト ID を取得するには、 Walletconnectにサインアップしてプロジェクトを作成します。環境変数にプロジェクト ID を指定したら、 $ yarn build && yarn start
を実行してバックエンドを起動し、バグがないことを確認します。
この時点で、ブラウザでhttp://localhost:3000
にアクセスすると、以下のインターフェースが表示されます。
次のステップこのマイルストーンに到達しました。おめでとうございます!パート 2 に進み、バックエンド サービスの開発を完了してください。
おかえりなさい!まだ読んでいない場合は、パート 1 をお読みください。それでは、パート 2「Web3 映画ストリーミング プラットフォームのバックエンド サービスの構築」に進みましょう。
バックエンドのスターター コードを提供しました。現在、サーバーを起動してブラウザーでhttp://localhost:9000
にアクセスすると、「ようこそ」メッセージが表示されます。この基盤を基に構築してみましょう。
現在、これらのコードはバックエンドのソース ディレクトリにあります。簡単に説明しましょう。
ユーティリティ ファイルこのフォルダーはbackend/src/utils
に完全にアドレス指定でき、HTTP 例外ハンドラー関数とファイル アップロード情報を処理するためのインターフェイスという 2 つの重要なファイルが含まれています。
このコードは、組み込みの JavaScript Error
クラスを拡張するカスタムHttpException
クラスを定義し、特定の HTTP ステータス コードとメッセージを持つエラー インスタンスの作成を可能にします。
https://gist.github.com/Daltonic/bb37e1d4c5f84bc9c10fcbb8c3e19621
このコードは、アップロードされたファイルを表すインターフェイスFileUpload
を定義し、名前、データ、サイズ、エンコーディングなどのプロパティを指定して、このバックエンド アプリケーションでファイルのアップロードを処理するための構造化された方法を提供します。
https://gist.github.com/Daltonic/64fb31bf3b19668a17d14f59e087a77e
そして、 backend/src
ルート フォルダーには、CORS とファイル アップロード サポートを備えた Express.js サーバーを設定し、「Welcome」メッセージをindex.ts
単一の GET ルートを定義し、エラーをキャッチしてカスタム HttpExceptions として再スローすることでエラーを処理し、環境変数で指定されたポート 9000 でサーバーを起動する index.ts ファイルがあります。
https://gist.github.com/Daltonic/8d76c3a212681d7bfe89b0792b0e707f
主要なファイルについて説明したので、 services
フォルダーに、アプリケーション内でそれぞれ異なる目的を果たす 2 つの新しいファイルを作成しましょう。
backend/src
フォルダーに、この場所にservices
という新しいフォルダーを作成します。ここで、2 つのサービスを作成します。
backend/src/services
フォルダーにsia.service.ts
という名前のファイルを作成し、以下の手順に従ってこのサービスを作成します。
このコードは、Sia API 設定と元の URL の環境変数で初期化するSiaService
クラスを定義し、Sia サービスとのやり取りを管理するための基盤を提供します。次に、このサービスの残りのコードを指定しましょう。
Sia Renterd へのファイルのアップロードSia ネットワークにファイルをアップロードするには、クラスに次の 3 つのメソッドを追加する必要があります。2 つはプライベートで、1 つはパブリックです。
このコードは、ループを使用して定義済みの文字列からランダムに文字を選択し、大文字と小文字、および数字で構成された指定された長さのランダムな文字列を生成するプライベート メソッドgenerateRandomString
を定義します。これを使用して、ファイルを Renterd に送信する前に各ファイルの名前を一意に変更します。
上記のコードは、Axios を使用して Sia Renterd にファイルをアップロードし、アップロードの進行状況とエラーを処理し、アップロードが失敗した場合に Axios 応答を返すかエラーをスローするプライベート メソッドuploadToSiaService
を定義します。
Renterd エンドポイントは API ドキュメントに記載されています。このドキュメントを確認するか、Sia Renterd API ドキュメントについて説明した以下のビデオをご覧ください。
ここで、後でアプリケーションのエンドポイントとして公開するパブリック メソッドを含めましょう。
このコードは、一意の識別子を生成し、ファイルをローカル キャッシュに保存し、Sia Renterd にアップロードして、ファイルの URL と成功メッセージを返すか、アップロードが失敗した場合はエラーをスローすることによってuploadFile
をアップロードするパブリック メソッド uploadFile を定義します。
Sia Renterd へのファイルのダウンロードSia ネットワークにファイルをダウンロードするには、クラスに次の 2 つのメソッドを追加する必要があります。1 つはプライベートで、もう 1 つはパブリックです。
このコードは、Sia サービスからファイルを取得し、それをローカルにキャッシュし、ファイルの読み取り可能なストリームを返し、エラーを処理し、ファイルが見つからない場合は 404 イメージを返すプライベート メソッドdownloadFromSiaService
を定義します。
これらの response_files をバックエンド ディレクトリで使用できるようにしておきます。そうしないと、 404.png
ファイルの呼び出し時にエラーが発生します。 backend
ディレクトリにresponse_files
という別のフォルダーを作成し、次の画像をそこにコピーします。
完璧です。それでは、このファイル ダウンロード サービスを完成させましょう。また、 SiaService
クラスに以下のメソッドを追加します。
このコードは、Sia Renterd からファイルを取得するためにプライベート メソッドdownloadFromSiaService
を呼び出すパブリック メソッドdownloadFile
を定義し、取得したファイルの読み取り可能なストリームを返します。
これらのさまざまなメソッドをそれぞれのエンドポイントに結合するときが来ました。現在は 1 つしかありませんが、ファイルのアップロードとダウンロード用にさらに 2 つ必要になります。ファイル ストリーミングでもダウンロード エンドポイントが使用されます。
backend/src/index.ts
ファイルに移動し、次のコードを使用してそのコンテンツを更新します。
このコードは、CORS とファイル アップロード サポートを備えた Express.js サーバーを設定し、ウェルカム メッセージ、Sia ネットワークへのファイル アップロード、Sia ネットワークからのファイル ダウンロードの 3 つのエンドポイントを定義します。ファイル操作の処理には SiaService クラスを使用し、エラー処理には HttpException を使用します。
視覚的な補助が必要な場合は、以下のビデオのこのセクションを視聴し、タイムスタンプ01:50:44で停止するようにしてください。
ファイルがキャッシュ内に留まる期間を制御して、サーバーが未使用のファイルでいっぱいにならないようにするには、キャッシュ管理サービスを作成する必要があります。このサービスが必要な唯一の理由は、データの遅延を減らすことであるということを理解することが重要です。
backend/src/services
フォルダーに移動し、 background.service.ts
というファイルを作成し、次のコード シーケンスを追加します。
このコードは、キャッシュ ディレクトリを設定し、 node-cron
ライブラリを使用して毎日のジョブをスケジュールし、バックグラウンド ジョブを初期化して確認メッセージを記録するBackgroundService
クラスを定義します。キャッシュ内の 7 日以上経過したファイルを削除するメソッドを作成しましょう。
古いファイルを削除するには、このメソッドをBackgroundService
クラスに追加します。
このコードは、ディレクトリを読み取り、各ファイルの作成時間をチェックし、ターゲット時間を超えたファイルを削除し、ジョブの開始と終了、およびdeleteOldFiles
や削除の成功をログに記録することで、7 日以上経過したファイルをキャッシュ ディレクトリから削除する deleteOldFiles というメソッドを定義します。
ここで、node-cron パッケージを利用してファイルの削除をいつ実行するかをスケジュールする関数を作成しましょう。
このコードは、毎日深夜 (00:00) にdeleteOldFiles
メソッドを実行して自動ファイル クリーンアップを実行する毎日の cron ジョブを設定します。
また、バックグラウンド サービス クラスのインスタンス化時に毎日のジョブをスケジュールするようにコンストラクター関数を更新する必要があります。
完璧です。最後に、初期化時にこのバックグラウンド操作をサーバー プロセスの一部として追加しましょう。backend backend/src/index.ts
ファイルに移動し、アプリ リスナー メソッドを更新してバックグラウンド サービス ファイルをインポートします。
$ yarn build && yarn start
を使用してバックエンド サービス コマンドを再実行すると、下の画像のようなターミナル出力が表示されます。
バックグラウンド サービス全体をどのようにコーディングしたかをご覧になりたい場合は、以下のビデオをご覧ください。タイムスタンプ02:16:07で停止するようにしてください。
次のステップおめでとうございます。これで、このチュートリアルの最後の部分であるパート 3に進む準備が整いました。
このチュートリアル シリーズの最後の部分に進み、バックエンドとフロントエンドを統合し、各部分を接続してファイル アップロード アプリケーションを完成させます。まず、フロントエンドの認証が稼働していることを確認します。
Frontend ディレクトリに 'config' という名前の新しいフォルダーを作成し、インデックス ファイルを追加します。パスは/frontend/config/index.tsx
になります。次に、次のコードを追加してみましょう。
このコードは、Web3 アプリケーションの Wagmi 構成を設定し、メタデータ、サポートされるチェーン、ウォレットやソーシャル ログイン オプションなどの認証設定を定義して、 config
エクスポートに保存します。また、認証状態を追跡するためのコンテキスト API を作成する必要があります。
コンテキスト API次に、フロントエンド ディレクトリ内に 'context' という名前の新しいフォルダーを作成し、インデックス ファイルを追加します。パスは/frontend/context/index.tsx
になります。次のコードを追加します。
このコードは、Wagmi と React Query を使用して Web3Modal プロバイダーを設定し、プロジェクト ID とテーマ変数を使用して Web3 モーダルを構成し、アプリケーションを WagmiProvider と QueryClientProvider でラップします。
レイアウトの更新: 上記の構成を含めるようにアプリケーション レイアウトを更新してみましょう/frontend/app/layout.tsx
に移動し、そのコードを以下のコードに置き換えます。
上記のコードは、メタデータ、フォント、スタイル、Web3 モーダル、トースト通知、ヘッダーやフッターなどのレイアウト コンポーネントのプロバイダーを含む、Next.js アプリケーションのルート レイアウトを設定します。
ログイン ボタンここで、 /frontend/app/components/layout/Header.tsx
/components/layout/Header.tsx および/frontend/app/components/shared/Menu.tsx
コンポーネントのログイン ボタンを有効にし、以下の情報を使用してコードを更新する必要があります。
このコードは、ロゴ、ナビゲーション リンク、カスタム メニュー、さまざまな画面サイズに対応するレスポンシブ デザインの Web3 モーダルを起動するログイン ボタンを含むナビゲーション バーの React コンポーネントを定義します。
ログイン ボタンをクリックして、お好みのプロバイダー、X、Facebook、Google、Discord、または Ethereum で続行すると、私たちが行った操作が機能したことの証拠として次の画像がポップアップ表示されます。
素晴らしいですね。さらに詳しく、データベースと NextJs API ベースのシステムをセットアップしてみましょう。プロセスについて不明な点がある場合は、下のビデオ セクションをご覧ください。02 :57:59 のマークで停止するようにしてください。
まず、NextJs 構成スクリプトを更新して、ページとエンドポイントを適切に処理し、リモート イメージを警告や精査から解放しましょう。
このコードは、API ルートの書き換えとイメージの最適化を設定し、任意の HTTPS ホスト名からのリモート イメージと localhost ドメインからのローカル イメージを許可する Next.js 構成オブジェクトを定義します。
データベース構成スクリプトこのアプリケーションでは SQLite を使用しますが、MYSQL や NOSQL プロバイダーなどのより堅牢なソリューションを使用することもできます。簡単にするために、SQLite フラット ファイルを使用して作業してみましょう。
/frontend/app/api/database.ts
ファイル パスを作成し、以下のコードを追加します。
このコードは、SQLite データベース接続を設定し、エラー処理と promise ベースの非同期実行を使用して、データベースに対して GET および POST リクエストを実行する 2 つの API 関数apiGet
とapiPost
定義します。データベースからデータを送信または取得する必要がある場合は、常にこれらのコードを使用します。
データベース移行スクリプトすべてのコンテンツを保持するためのデータベース フラット ファイルとテーブルの両方を作成する必要があります/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 ファイル/frontend/app/api/movies/create/route.ts
を作成し、以下のコードを追加します。
このコードは、POST リクエストを処理し、ムービー データを検証および処理し、一意のスラッグを生成し、エラーを処理して JSON 応答を返すと同時に apiPost 関数を使用してデータをデータベースに挿入するエンドポイントを定義します。
ムービーエンドポイントの更新ムービーを更新するには、ユーザー ID、スラッグ、およびムービーの作成時に提供されるその他の情報が必要です。 /frontend/app/api/movies/update/route.ts
ファイルパスを作成し、以下のコードを追加します。
このコードは、apiPost 関数を使用して、ムービーを更新し、必要なプロパティを検証し、データベース内のムービー データを更新するための SQL クエリを実行するための POST リクエストを処理するエンドポイントを定義します。
ムービーエンドポイントの削除ムービーを削除するには、ムービーのユーザー ID とスラッグなど/frontend/app/api/movies/delete/route.ts
情報が必要です。/frontend/app/api/movies/delete/route.ts ファイルパスを作成し、そこに以下のコードを追加します。
このコードは、映画の削除、必須プロパティ (userId と slug) の検証、apiPost 関数を使用してデータベースから映画を削除する SQL クエリの実行に関する POST リクエストを処理するエンドポイントを定義します。
すべての映画エンドポイント映画を取得するために必要なオプションのデータは pageSize と userId です。これら/frontend/app/api/movies/all/route.ts
、結果をフィルタリングおよびページ分割するためのクエリ パラメータとして渡すことができます。/frontend/app/api/movies/all/route.ts ファイル パスを作成し、以下のコードを追加します。
上記のコードは、映画を取得するための GET リクエストを処理するエンドポイントを定義し、オプションで userId によるフィルタリングと pageSize によるページ分割を許可し、結果を JSON 形式で返します。
単一の映画エンドポイント単一の映画を取得するには、映画のスラッグというデータが必要です。/frontend/app/api/movies/[slug]/route.ts ファイル パスを/frontend/app/api/movies/[slug]/route.ts
し、以下のコードを追加します。
このコードは、スラッグで映画を取得し、スラッグ パラメータを検証し、apiGet 関数を使用してデータベースから映画データを取得するための SQL クエリを実行する GET リクエストを処理するエンドポイントを定義します。
これで、このアプリケーションに必要なすべてのエンドポイントがマークされました。これらのエンドポイントをよりよく理解するために視覚的な補助が必要な場合は、以下のビデオをご覧ください。タイムスタンプ03:48:22で停止するようにしてください。
私たちの仕事は、事前にコード化されたコンポーネントとページを確認して更新し、それぞれの目的と機能を説明し、既存のコードに加えた変更を文書化することです。まず、 api
ディレクトリに以前に作成したエンドポイントと対話するためのサービスを作成します。
/frontend/app/services/api.service.ts
ファイル パスを作成し、以下のコードを追加します。
このサービスは、映画データベースと対話するための一連の機能を提供し、アプリケーションが映画の取得、スラグによる単一の映画の取得、新しい映画の作成、既存の映画の更新、映画の削除、API リクエストを使用したファイルのアップロード、エラーの処理などを行うことを可能にします。
アプリケーションに関連するさまざまなページを確認して更新しましょう。多くの部分を変更する必要はなく、ここで強調表示されている部分だけを変更すれば十分です。
ムービーページの作成
このページは、React および Wagmi ライブラリを使用して、ユーザーがビデオおよび画像ファイルをアップロードし、ムービーの詳細を入力し、検証とエラー処理を行ってフォームを送信してムービーを公開できるムービー公開フォームです。
次に、 /frontend/app/pages/create/page.tsx
/create/page.tsx にあるファイルを以下のコードで更新します。
このコードでは、元のコードと比較して次の変更が加えられています。
api.service
からcreateMovie
関数をインポートし、 handleSubmit
関数で使用して新しいムービーを作成しました。createMovie
関数呼び出しにuserId
パラメータを追加し、 useAccount
フックからユーザーのアドレスを渡します。createMovie
によって返された promise を処理するためにtoast.promise
を使用するようにhandleSubmit
関数を更新しました。handleSubmit
関数のcreateMovie
関数呼び出しにエラー処理を追加しました。
これらの変更により、フォームは映画のデータを API に送信し、新しい映画のエントリを作成すると同時に、エラーを処理して成功メッセージを表示できるようになります。
ムービー編集ページ
このムービー編集ページでは、承認されたユーザーがムービーの詳細を更新し、ポスターやビデオをアップロードし、変更を保存できます。また、ユーザーがムービーを編集できるように特別に設計された React、Wagmi、Next.js を利用して、検証とエラー処理も行えます。
次に、 /frontend/app/pages/movies/edit/[slug]/page.tsx
/movies/edit/[slug]/page.tsx にあるファイルを以下のコードで更新します。
元のコードとは異なるコードへのアップグレードは次のとおりです。
@/app/services/api.service
からfetchMovie
とupdateMovie
関数をインポートし、それぞれuseEffect
フックとhandleSubmit
関数で使用しました。posters.find()
メソッドをfetchMovie
関数に置き換えました。updateMovie
関数を呼び出すようにhandleSubmit
関数を更新しました。handleSubmit
関数のupdateMovie
関数呼び出しにエラー処理を追加しました。
これらの変更により、アプリケーションは API エンドポイントと対話して映画データを取得および更新できるようになりました。一方、元のコードはローカルのposters
配列に依存していました。
ホームページ
このホームページは、React と Next.js を使用して、バナー コンポーネント、映画のリスト (API ソースまたは読み込み UI から)、サブスクリプション オプションをレンダリングし、ユーザーにとって魅力的で有益なランディング ページを提供します。
/frontend/app/pages/page.tsx
にあるファイルを次のコードで更新します。
ホームページに加えた変更は次のとおりです。
./services/api.service
からfetchMovies
関数をインポートし、 useEffect
フックで使用して API からムービー データを取得しました。posters
データを、API からデータを取得するfetchMovies
関数呼び出しに置き換えました。movies
状態を設定する前に、 fetchMovies
によって返された promise が解決されるのを待機するためのawait
キーワードが追加されました。これらの変更により、アプリケーションはローカル データに依存するのではなく、API から映画データを取得できるようになり、アプリケーションがより動的でデータ駆動型になります。
ユーザーアカウントページ
このページには、現在接続しているユーザーが投稿した映画のリストが表示され、データの取得中に読み込みスケルトン プレースホルダーが表示され、Wagmi と react-loading-skeleton を使用して、ユーザーがまだアカウントを接続していない場合は接続するように促すメッセージが表示されます。
/frontend/app/pages/account/page.tsx
にあるファイルを次のコードで更新します。
このページに加えられた変更は次のとおりです。
@/app/services/api.service
からfetchMovies
関数をインポートし、 useEffect
フックで使用して API からムービー データを取得しました。posters
データを、API からデータを取得するfetchMovies
関数呼び出しに置き換えました。fetchMovies
関数に引数としてaddress
を渡します。fetchMovies
関数がこのロジックを処理するようになったため、ムービー リストをレンダリングする前のaddress
の条件チェックが削除されました。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 呼び出しに置き換えました。deleteMovie
関数を呼び出して応答を処理するようにhandleSubmit
関数を更新しました。fetchMovie
およびfetchMovies
関数を呼び出すようにuseEffect
フックを更新しました。
これらの変更により、アプリケーションは API と対話して映画データを取得および削除し、削除プロセス中にユーザーに通知を表示します。
以下のビデオのこの部分では、これらのページをエンドポイントに統合する実践的な方法を紹介します。問題が発生した場合は、この部分を自由に視聴してください。タイムスタンプ04:57:41で停止するようにしてください。
アプリケーション内の各コンポーネントの目的について説明しましょう。変更が必要なコンポーネントはすべて更新します。
バナーコンポーネント
このコンポーネントは、映画のバナーの背景画像の回転を表示し、5 秒ごとに映画の画像の配列を循環して、シンプルで自動的なスライドショー効果を作成します。このコンポーネント コードは、 /frontend/app/components/home/Banner.tsx
で確認できます。
ポスターコンポーネント
このコンポーネントは、Swiper ライブラリを使用して、自動再生、ページネーション、ナビゲーションなどの機能を備えた映画ポスターのレスポンシブでインタラクティブなカルーセルを表示し、プロパティとして渡された映画のリストを表示し、さまざまな画面サイズに適応する動的なレイアウトを備えています。このコンポーネント コードは、 /frontend/app/components/home/Posters.tsx
で評価できます。
ポスターUIコンポーネント
このコンポーネントは、 react-loading-skeleton ライブラリを使用して、映画ポスター セクションのプレースホルダー スケルトン レイアウトを表示します。このレイアウトでは、「posters」プロパティに基づいて動的な数のスケルトン ポスターが表示され、さまざまな画面サイズに適応するレスポンシブ デザインにより、実際のポスター データが取得されて表示されるまで読み込み状態が示されます。このコンポーネント コードは、 /frontend/app/components/home/PosterUI.tsx
で評価できます。
サブスクリプションコンポーネント
このコンポーネントは、サブスクリプション プラン セクションを表示し、さまざまなダミー プランの詳細、価格、特典を紹介します。レスポンシブ グリッド レイアウトとインタラクティブなホバー効果を利用してユーザー エクスペリエンスを向上させ、ユーザーがニーズに合ったプランを選択できるようにします。このコンポーネント コードは、 /frontend/app/components/home/Subscription.tsx
app/components/home/Subscription.tsx で確認できます。
ヘッダーコンポーネント
このコンポーネントは、ページ上部に固定ナビゲーション バーをレンダリングします。このナビゲーション バーには、ロゴ、さまざまなセクションへのリンクを含むナビゲーション メニュー、レスポンシブ デザイン用のメニュー切り替えボタン、ログイン ボタンが備わっており、アプリケーション全体で一貫性がありアクセスしやすいヘッダー セクションを提供します。このコンポーネント コードは、 /frontend/app/components/layout/Header.tsx
components/layout/Header.tsx で確認できます。
フッターコンポーネント
このコンポーネントは、ページの下部にフッター セクションをレンダリングします。このフッター セクションには、アプリケーションのロゴ、簡単な説明、ナビゲーション リンク、連絡先情報、Sia Foundation が提供する分散型ストレージ ソリューションに関するクレジットが表示され、関連情報とリンクを含む明確で整理されたフッター セクションが提供されます。このコンポーネント コードは、 /frontend/app/components/layout/Footer.tsx
で確認できます。
メニューコンポーネント
このコンポーネントは、レスポンシブなメニュー切り替えボタンをレンダリングします。このボタンをクリックすると、ナビゲーション リンクを含むドロップダウン メニューが開いたり閉じたりします。これにより、ユーザーは小さい画面でアプリケーションのさまざまなセクションにアクセスできるようになります。一方、ナビゲーション リンクがすでに表示されている大きい画面ではメニューを非表示にします。このコンポーネント コードは、 /frontend/app/components/shared/Menu.tsx
で評価できます。
映画カードコンポーネント
このコンポーネントは、ホバー効果で映画のポスターを 1 つ表示し、映画の名前、公開年、背景の概要などの追加情報を表示するとともに、映画の詳細ページへのリンクとしても機能し、レスポンシブ デザインとアニメーション トランジションを利用してユーザー エクスペリエンスを向上させます。このコンポーネント コードは、 /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開発に関するチュートリアルやヒントを共有しています。また、ブロックチェーン分野の最新動向に関する記事を定期的にオンラインに投稿しています。