Giới thiệu Web đang phát triển và các công nghệ Web3 đang cách mạng hóa các ngành công nghiệp truyền thống, bao gồm cả phát trực tuyến video. Các nền tảng như đang dẫn đầu, cung cấp các giải pháp thay thế phi tập trung cho YouTube và Rumble. Tương tự như vậy, không giống như các nhà cung cấp cũ như Google Drive và Dropbox, đang chuyển đổi lưu trữ dữ liệu, cung cấp phương pháp tiếp cận tập trung vào quyền riêng tư và lấy người dùng làm trung tâm. Odysee Sia bằng NextJs, TypeScript, Tailwind CSS và Sia Renterd. Chuỗi hướng dẫn này sẽ hướng dẫn bạn tạo một ứng dụng phi tập trung tận dụng công nghệ blockchain của Sia để đảm bảo quyền sở hữu dữ liệu và quyền riêng tư của người dùng. Hãy tham gia cùng chúng tôi trong hành trình xây dựng một dApp phát trực tuyến phim Web3 tiên tiến Đến cuối hướng dẫn này, bạn sẽ có được chuyên môn để: Xây dựng một nền tảng phát trực tuyến phim đầy đủ chức năng để chia sẻ với bạn bè hoặc sử dụng làm dự án ở trường Ra mắt ứng dụng SaaS (Phần mềm dưới dạng dịch vụ) của riêng bạn Mở khóa tiềm năng của công nghệ Web3 trong ngành phát trực tuyến video để xem dự án đang hoạt động và để biết thêm nhiều nội dung sáng tạo như thế này! Hãy xem video demo bên dưới đăng ký kênh của chúng tôi https://www.youtube.com/watch?v=Hgfdesry8Ss&embedable=true Điều kiện tiên quyết Để thực hiện theo, hãy đảm bảo bạn đã cài đặt các công cụ sau và việc quen thuộc với các ngăn xếp cũng sẽ giúp bạn hiểu rõ hơn: NodeJs Tiếp theoJs CSS của Tailwind Kiểu chữ Docker (bắt buộc) Loạt bài gồm ba phần này sẽ đề cập đến: - Mạng thử nghiệm Renterd Zen, Cài đặt gói và biến môi trường. Phần 1: Thiết lập dự án - Xây dựng dịch vụ Backend Phần 2: Phát triển Backend - Tích hợp giao diện người dùng với dịch vụ quản trị. Phần 3: Phát triển giao diện người dùng Nếu bạn thích xem toàn bộ quá trình phát triển, , trong danh sách phát, mọi thứ được viết ở đây và nhiều nội dung khác đều được ghi lại trong các video. tôi khuyên bạn nên xem danh sách phát này Sau khi đã nói những điều đó, chúng ta hãy cùng bắt đầu thực hiện dự án này. Thiết lập dự án – Phần 1 Chúng ta sẽ bắt đầu bằng cách sao chép một kho lưu trữ đã chuẩn bị bao gồm tập lệnh docker compose của Sia Renterd và các dịch vụ backend và frontend. Chạy các lệnh sau: $ git clone https://github.com/Daltonic/sia_vid_tv $ cd sia_vid_tv Bây giờ, điều quan trọng là chúng ta phải chuyển sang nhánh khởi động trên dự án GitHub mới được sao chép này và chạy lệnh bên dưới để hoàn tất. $ git checkout 01_starter_branch Tiếp theo, hãy thiết lập biến môi trường liên quan cho dịch vụ Renterd này. Tạo tệp tại thư mục gốc của dự án này và áp dụng các khóa bên dưới: .env RENTERD_SEED=<RENTERD_SEED_PHRASE> RENTERD_API_PASSWORD=<YOUR_PREFERED_PASSWORD> RENTERD_LOG_LEVEL=debug RENTERD_LOG_DATABASE_LEVEL=error Để có được các khóa API này, bạn sẽ cần cài đặt Sia Renterd trên máy của mình; vui lòng xem video ngắn bên dưới để tóm tắt lại toàn bộ nội dung. https://www.youtube.com/watch?v=78XCHGWZwhA&embedable=true Tạo cụm từ hạt giống với ứng dụng Renterd như trong video trên và đưa nó vào biến môi trường của bạn theo hướng dẫn trong video trên. Thay thế mật khẩu bằng mật khẩu mà bạn có thể dễ nhớ. Tiếp theo, chúng ta cần cài đặt Docker bằng cách nếu bạn chưa tải. Ngoài ra, hãy sử dụng nền tảng trực tuyến miễn phí như hoặc VPS để chạy phiên bản Docker, nếu có thể. Nếu không, hãy cài đặt trên máy tính cục bộ của bạn. tải xuống từ trang web chính thức Gitpod Cuối cùng, chúng ta có thể tạo một container docker bằng cách chạy lệnh docker sau tại gốc của dự án này. Đảm bảo rằng terminal ở cùng vị trí thư mục với tệp này. docker-compose.yml $ docker compose -f "docker-compose.yml" up -d --build Lưu ý lệnh để kéo xuống container: . Chạy lệnh này khi bạn muốn tắt phiên bản Docker của mình (nhưng không phải bây giờ). $ docker compose -f "docker-compose.yml" down Nếu bạn thực hiện đúng các hướng dẫn trên, bạn sẽ thấy giao diện bên dưới khi truy cập trình duyệt tại . http://localhost:9880 Nhập mật khẩu (từ biến môi trường của bạn) để đăng nhập. Sau đó, làm theo quy trình cấu hình trong video bên dưới để thiết lập phiên bản Sia Renterd của bạn để tải tệp lên, tải xuống và phát trực tuyến. https://www.youtube.com/watch?v=ZJ8YWdVTWUA&t=401s&embedable=true Video trên bắt đầu từ phút , vui lòng dừng lại ở phút , phần này sẽ hướng dẫn trực quan cho bạn về quy trình cấu hình Renterd. 6:41 20:01 Xin lưu ý rằng quá trình đồng bộ hóa blockchain, cùng với việc khớp máy chủ, mất tới để hoàn tất, vì vậy bạn sẽ phải kiên nhẫn với toàn bộ quá trình. 25 min Vui lòng tạo một bucket mới trên Renterd có tên là , nơi lưu trữ tất cả các tệp của chúng tôi cho dự án này. Nếu bạn đã thực hiện thành công các hướng dẫn trên, nút Renterd của bạn sẽ sẵn sàng để tải lên và tải xuống. Xem hình ảnh bên dưới. vidtv Thật tuyệt vời. Tại thời điểm này, dịch vụ Renterd của chúng tôi đã sẵn sàng để bắt đầu nhận tệp, nhưng chúng tôi cần phải giao tiếp với nó theo cách lập trình. Chúng ta hãy kết thúc phần một của hướng dẫn này bằng cách thiết lập các gói và biến môi trường cho phần phụ trợ và phần giao diện. Thực hiện các hướng dẫn sau để cài đặt các gói dịch vụ phụ trợ và sẵn sàng cho việc phát triển thêm. Thiết lập dự án phụ trợ Điều hướng đến thư mục phụ trợ từ phiên bản thiết bị đầu cuối mới bằng các lệnh sau: $ cd backend $ yarn install #you can also use npm install $ touch .env #or mannually create it at the root of the backend directory Tiếp theo, cung cấp thông tin sau vào biến môi trường. SIA_API_BUCKET=vidtv SIA_API_PASSWORD=<YOUR_PREFERED_PASSWORD> SIA_API_BASE_URL=http://localhost:9880 ORIGIN=http://localhost:9000 PORT=9000 Và bây giờ, hãy chạy để chạy chương trình phụ trợ và cũng để xác nhận rằng chương trình không có lỗi nào. $ yarn build && yarn start Cuối cùng, chạy các lệnh sau để cài đặt các gói liên quan đến frontend. Sau đó, chúng ta sẽ chạy nó. Thiết lập dự án Frontend Điều hướng đến thư mục phụ trợ từ phiên bản thiết bị đầu cuối mới bằng các lệnh sau: $ cd frontend $ yarn install #you can also use npm install $ touch .env #or mannually create it at the root of the backend directory Tiếp theo, cung cấp thông tin sau vào biến môi trường. NEXT_PUBLIC_PROJECT_ID=<YOUR_WALLET_CONNECT_ID> NEXT_PUBLIC_FILE_SERVICE_URL=http://localhost:9000 Đăng ký và tạo một dự án với để lấy ID dự án của bạn. Sau khi bạn đã cung cấp ID dự án cho biến môi trường, hãy chạy để khởi động backend và cũng để xác nhận rằng nó không có bất kỳ lỗi nào. Walletconnect $ yarn build && yarn start Lúc này, bạn sẽ thấy giao diện bên dưới khi truy cập trình duyệt tại . http://localhost:3000 Xin chúc mừng vì đã đạt được cột mốc này! để hoàn tất quá trình phát triển dịch vụ phụ trợ. Bước tiếp theo Tiến hành Phần 2 Dịch vụ Backend – Phần 2 Vui lòng đọc qua Phần 1 nếu bạn chưa đọc. Bây giờ, chúng ta hãy cùng tìm hiểu Phần 2: Xây dựng dịch vụ phụ trợ cho nền tảng phát trực tuyến phim web3 của chúng tôi. Chào mừng trở lại! Chúng tôi đã cung cấp mã khởi động cho phần phụ trợ, hiện đang hiển thị thông báo "Chào mừng" khi bạn khởi động máy chủ và truy cập trong trình duyệt của bạn. Hãy xây dựng trên nền tảng này. http://localhost:9000 Hiện tại chúng tôi có các mã này trong thư mục nguồn của phần phụ trợ. Tôi xin giải thích ngắn gọn cho bạn. Thư mục này có thể được định địa chỉ đầy đủ là chứa hai tệp cần thiết: một hàm xử lý ngoại lệ HTTP và một giao diện để xử lý thông tin tải tệp lên. Tệp tiện ích backend/src/utils Mã này định nghĩa một lớp tùy chỉnh mở rộng lớp của JavaScript tích hợp, cho phép tạo các trường hợp lỗi với mã trạng thái HTTP và thông báo cụ thể. HttpException Error https://Gist.github.com/Daltonic/bb37e1d4c5f84bc9c10fcbb8c3e19621 Mã này định nghĩa giao diện biểu diễn tệp đã tải lên, chỉ định các thuộc tính của tệp như tên, dữ liệu, kích thước, mã hóa, v.v., cung cấp một phương pháp có cấu trúc để xử lý tệp tải lên trong ứng dụng phụ trợ này. FileUpload https://Gist.github.com/Daltonic/64fb31bf3b19668a17d14f59e087a77e Và sau đó tại thư mục gốc , chúng ta có tệp thiết lập máy chủ Express.js với CORS và hỗ trợ tải tệp lên, định nghĩa một tuyến GET duy nhất trả về thông báo "Welcome" và xử lý lỗi bằng cách bắt và gửi lại chúng dưới dạng HttpException tùy chỉnh, sau đó khởi động máy chủ trên cổng 9000 như đã chỉ định trong các biến môi trường. backend/src index.ts https://Gist.github.com/Daltonic/8d76c3a212681d7bfe89b0792b0e707f Bây giờ chúng ta đã tìm hiểu các tệp chính, hãy tạo hai tệp mới trong thư mục , mỗi tệp có mục đích riêng biệt trong ứng dụng của chúng ta. services Tệp dịch vụ Trong thư mục , tạo một thư mục mới có tên là tại vị trí này, đây là nơi chúng ta sẽ tạo hai dịch vụ: backend/src services : Xử lý việc tải lên, tải xuống, phát trực tuyến và lưu trữ đệm tệp, giao tiếp với dịch vụ Renterd. Dịch vụ Sia : Quản lý các tệp được lưu trong bộ nhớ đệm, tự động xóa chúng sau 7 ngày vào lúc nửa đêm hằng ngày. Dịch vụ nền Dịch vụ Sia Hãy tạo một tệp có tên tại thư mục và làm theo các bước dưới đây để xây dựng dịch vụ này. sia.service.ts backend/src/services https://Gist.github.com/Daltonic/a82a0c1cf8d3e7b31702b66eeead3718?embedable=true Mã này định nghĩa một lớp khởi tạo với các biến môi trường cho các thiết lập API Sia và một URL gốc, cung cấp nền tảng để quản lý các tương tác với dịch vụ Sia. Bây giờ, chúng ta hãy cung cấp phần còn lại của các mã cho dịch vụ này. SiaService Để tải tệp lên Mạng Sia, chúng ta sẽ cần thêm ba phương thức này vào lớp, trong đó hai phương thức sẽ là riêng tư và một phương thức sẽ là công khai. Tải tệp lên Sia Renterd https://Gist.github.com/Daltonic/ddf74dffc5ac1005585f7ae3ad55c286?embedable=true Mã này định nghĩa một phương thức riêng tạo ra một chuỗi ngẫu nhiên có độ dài được chỉ định, bao gồm các chữ cái viết hoa, viết thường và số, sử dụng vòng lặp để chọn ngẫu nhiên các ký tự từ một chuỗi được xác định trước. Chúng tôi sẽ sử dụng nó để đổi tên từng tệp một cách duy nhất trước khi chuyển tệp đến Renterd. generateRandomString https://Gist.github.com/Daltonic/e6a82ac4af9eca9c881f4e0bdd1d682b?embedable=true Đoạn mã trên định nghĩa phương thức riêng dùng để tải tệp lên Sia Renterd bằng Axios, xử lý tiến trình và lỗi tải lên, trả về phản hồi của Axios hoặc báo lỗi nếu tải lên không thành công. uploadToSiaService Các điểm cuối Renterd được viết trong tài liệu API mà bạn có thể kiểm tra hoặc xem video bên dưới, trong đó tôi đã giải thích cách viết tài liệu API của Sia Renterd. https://www.youtube.com/watch?v=zOmUMz0DBQM&embedable=true Bây giờ chúng ta hãy đưa phương thức công khai mà sau này chúng ta sẽ đưa vào như một điểm cuối trong ứng dụng. https://Gist.github.com/Daltonic/ce565350160a39c4d9f0abc0b7e7dc26?embedable=true Mã này định nghĩa phương thức công khai để tải tệp lên bằng cách tạo một mã định danh duy nhất, lưu tệp vào bộ nhớ đệm cục bộ, sau đó tải tệp lên Sia Renterd, trả về URL của tệp và thông báo thành công hoặc báo lỗi nếu tải lên không thành công. uploadFile Để tải tệp xuống Mạng Sia, chúng ta sẽ cần thêm hai phương thức này vào lớp, một phương thức sẽ là riêng tư và phương thức còn lại sẽ là công khai. Tải tệp xuống Sia Renterd https://Gist.github.com/Daltonic/b401e92d510ffddc8a0b7301d526f702?embedable=true Mã này định nghĩa phương thức riêng để truy xuất tệp từ dịch vụ Sia, lưu trữ cục bộ và trả về luồng tệp có thể đọc được, xử lý lỗi và trả về hình ảnh 404 nếu không tìm thấy tệp. downloadFromSiaService Hãy để các response_files đó có sẵn trong thư mục backend, nếu không chúng ta sẽ gặp lỗi khi gọi tệp . Tại thư mục , hãy tạo một thư mục khác có tên là và sao chép các hình ảnh sau vào đó. 404.png backend response_files Hoàn hảo, bây giờ chúng ta hãy hoàn thành dịch vụ tải xuống tệp này. Ngoài ra, hãy thêm phương thức bên dưới vào lớp . SiaService https://Gist.github.com/Daltonic/1f1a99c82d5b15693eaa2d8d2482f6c2?embedable=true Mã này định nghĩa phương thức công khai gọi phương thức riêng tư để truy xuất tệp từ Sia Renterd và trả về luồng có thể đọc được của tệp đã truy xuất. downloadFile downloadFromSiaService Điểm cuối dịch vụ Đã đến lúc chúng ta ghép nối những phương pháp khác nhau này với các điểm cuối tương ứng của chúng, hiện tại, chúng ta chỉ có một, nhưng chúng ta sẽ cần thêm hai phương pháp nữa để tải lên và tải xuống tệp. Truyền phát tệp cũng sẽ sử dụng điểm cuối tải xuống. Đi tới tệp và cập nhật nội dung của tệp bằng các mã này. backend/src/index.ts https://Gist.github.com/Daltonic/c8dec40acbc47b2582c651e04fae432f?embedable=true Mã này thiết lập máy chủ Express.js với CORS và hỗ trợ tải tệp lên, xác định ba điểm cuối: thông báo chào mừng, tải tệp lên Mạng Sia và tải tệp xuống từ Mạng Sia, sử dụng lớp SiaService để xử lý các hoạt động của tệp và HttpException để xử lý lỗi. Hãy xem phần video bên dưới nếu bạn cần hỗ trợ trực quan, hãy dừng lại ở mốc thời gian . 01:50:44 https://www.youtube.com/watch?v=ZJ8YWdVTWUA&t=3795&si=A6fF8n8Pd92i6weM&embedable=true Chúng ta cần tạo một dịch vụ quản lý bộ nhớ đệm để đảm bảo máy chủ của chúng ta không chứa đầy các tệp không sử dụng bằng cách kiểm soát thời gian lưu trữ tệp trong bộ nhớ đệm. Điều quan trọng cần biết là lý do duy nhất chúng ta cần dịch vụ này là để giảm . độ trễ dữ liệu Dịch vụ nền tảng Đi tới thư mục và tạo một tệp có tên là và thêm các chuỗi mã sau vào đó. backend/src/services background.service.ts https://Gist.github.com/Daltonic/bc62ccefd72cec85772dedd311afbffd?embedable=true Mã này định nghĩa một lớp thiết lập thư mục bộ nhớ đệm và lên lịch các tác vụ hàng ngày bằng thư viện , khởi tạo các tác vụ nền và ghi nhật ký thông báo xác nhận. Hãy tạo một phương thức chịu trách nhiệm xóa các tệp cũ hơn 7 ngày trong bộ nhớ đệm. BackgroundService node-cron Thêm phương thức này vào lớp . Xóa tệp cũ BackgroundService https://Gist.github.com/Daltonic/43da392512b88b6abf068be62d14eb7e?embedable=true Mã này định nghĩa một phương thức có tên là có tác dụng xóa các tệp khỏi thư mục bộ nhớ đệm có tuổi đời hơn 7 ngày bằng cách đọc thư mục, kiểm tra thời gian tạo của từng tệp, xóa các tệp vượt quá thời gian mục tiêu, ghi lại thời điểm bắt đầu và kết thúc công việc cũng như bất kỳ lỗi hoặc xóa thành công nào. deleteOldFiles Bây giờ, chúng ta hãy viết một hàm sử dụng gói node-cron để lên lịch thời điểm thực hiện xóa tệp. https://Gist.github.com/Daltonic/18b60b0bc1f7414a306f01f9087db435?embedable=true Mã này thiết lập một tác vụ cron hàng ngày để chạy phương thức vào lúc nửa đêm (00:00) hàng ngày để thực hiện dọn dẹp tệp tự động. deleteOldFiles Chúng ta cũng cần cập nhật hàm xây dựng để lên lịch cho các công việc hàng ngày khi khởi tạo lớp dịch vụ nền. https://Gist.github.com/Daltonic/5f608cd3793ff6deea56c262bdfbc395?embedable=true Hoàn hảo, cuối cùng, hãy thêm hoạt động nền này như một phần của quy trình máy chủ khi khởi tạo. Đi đến tệp và cập nhật phương thức trình lắng nghe ứng dụng để nhập tệp dịch vụ nền. backend/src/index.ts https://Gist.github.com/Daltonic/7966a7b27fa7eade2c6d1a7e60b2e530?embedable=true Bạn nên chạy lại lệnh dịch vụ phụ trợ bằng cách sử dụng và xem bản in đầu cuối như trong hình bên dưới. $ yarn build && yarn start Nếu bạn muốn xem cách tôi mã hóa toàn bộ dịch vụ nền, video bên dưới là dành cho bạn; chỉ cần đảm bảo bạn dừng lại ở mốc thời gian . 02:16:07 https://www.youtube.com/watch?v=ZJ8YWdVTWUA&t=8167&si=4DZ27j0lqwufUgRf&embedable=true Xin chúc mừng, bây giờ bạn đã sẵn sàng cho phần cuối cùng của hướng dẫn này, đó là . Bước tiếp theo Phần 3 Chúng ta hãy cùng đi sâu vào phần cuối của loạt bài hướng dẫn này, nơi chúng ta sẽ tích hợp phần phụ trợ với phần giao diện người dùng, kết nối các phần để hoàn thiện ứng dụng tải tệp lên. Chúng ta sẽ bắt đầu bằng cách đảm bảo rằng xác thực trong phần giao diện người dùng được thiết lập và chạy. Xác thực Web3 Modal – Phần 3 Tạo một thư mục mới có tên 'config' trong thư mục Frontend và thêm một tệp chỉ mục, tạo ra đường dẫn . Bây giờ, hãy thêm các mã sau vào đó. /frontend/config/index.tsx https://Gist.github.com/Daltonic/38bbe9fa325fb793dd59136ebdea8b43?embedable=true Mã này thiết lập cấu hình Wagmi cho ứng dụng Web3 của chúng tôi, xác định siêu dữ liệu, chuỗi được hỗ trợ và cài đặt xác thực, bao gồm tùy chọn đăng nhập bằng ví và mạng xã hội, và lưu trữ trong tệp xuất . Chúng tôi cũng cần tạo API ngữ cảnh để theo dõi trạng thái xác thực. config Tiếp theo, tạo một thư mục mới có tên 'context' vẫn trong thư mục Frontend và thêm một tệp chỉ mục, tạo ra đường dẫn . Thêm các mã sau vào đó. API ngữ cảnh /frontend/context/index.tsx https://Gist.github.com/Daltonic/db7330a9159ff83727cda0a384fd907e?embedable=true Mã này thiết lập nhà cung cấp Web3Modal bằng Wagmi và React Query, cấu hình Web3 modal với ID dự án và các biến chủ đề, sau đó gói ứng dụng trong WagmiProvider và QueryClientProvider. : Hãy cập nhật bố cục ứng dụng của chúng ta để bao gồm các cấu hình trên. Truy cập và thay thế mã của nó bằng mã bên dưới. Cập nhật Bố cục /frontend/app/layout.tsx https://Gist.github.com/Daltonic/2b54f191d56fa02f0ae3974bd8ffd11b?embedable=true Đoạn mã trên thiết lập bố cục gốc cho ứng dụng Next.js, bao gồm siêu dữ liệu, phông chữ, kiểu và nhà cung cấp cho Web3 modal, thông báo toast và các thành phần bố cục như đầu trang và chân trang. Bây giờ, chúng ta cần kích hoạt các nút đăng nhập trong các thành phần và , đồng thời cập nhật mã của chúng bằng thông tin bên dưới. Nút Đăng nhập /frontend/app/components/layout/Header.tsx /frontend/app/components/shared/Menu.tsx https://Gist.github.com/Daltonic/f9f60e85c18da94a5bbc97d1acb3d423?embedable=true Mã này định nghĩa một thành phần React cho thanh điều hướng bao gồm logo, liên kết điều hướng, menu tùy chỉnh và nút đăng nhập để khởi chạy Web3 Modal với thiết kế đáp ứng cho nhiều kích thước màn hình khác nhau. Những hình ảnh sau đây sẽ hiện lên như bằng chứng cho thấy những gì chúng tôi đã làm có hiệu quả khi bạn nhấp vào nút đăng nhập và tiếp tục với nhà cung cấp bạn thích, X, Facebook, Google, Discord hoặc Ethereum. Tuyệt vời, chúng ta hãy đi sâu hơn và thiết lập cơ sở dữ liệu và hệ thống dựa trên API NextJs của chúng ta. Nếu có bất kỳ sự nhầm lẫn nào về quy trình, vui lòng xem phần video bên dưới; chỉ cần đảm bảo bạn dừng lại ở mốc . 02:57:59 https://www.youtube.com/watch?v=ZJ8YWdVTWUA&t=9305&si=OadhxKlut7o3iLl5&embedable=true Tập lệnh cơ sở dữ liệu Đầu tiên, hãy cập nhật tập lệnh cấu hình NextJs để xử lý đúng các trang và điểm cuối của chúng ta và giải phóng hình ảnh từ xa khỏi các cảnh báo và sự giám sát. https://Gist.github.com/Daltonic/a4ecb4d168f8bb01cb8abb600653c4cf?embedable=true Mã này định nghĩa một đối tượng cấu hình Next.js thiết lập ghi lại tuyến API và tối ưu hóa hình ảnh, cho phép hình ảnh từ xa từ bất kỳ tên máy chủ HTTPS nào và hình ảnh cục bộ từ miền localhost. Chúng ta sẽ sử dụng SQLite cho ứng dụng này, nhưng bạn có thể sử dụng giải pháp mạnh mẽ hơn như nhà cung cấp MYSQL hoặc NOSQL. Để đơn giản, hãy làm việc với tệp phẳng SQLite. Database Config Script Tạo đường dẫn tệp và thêm đoạn mã bên dưới vào đó. /frontend/app/api/database.ts https://Gist.github.com/Daltonic/b699c52587b28c2d9435827837019633?embedable=true Mã này thiết lập kết nối cơ sở dữ liệu SQLite, định nghĩa hai hàm API, và , để thực hiện các yêu cầu GET và POST trên cơ sở dữ liệu, với xử lý lỗi và thực thi không đồng bộ dựa trên lời hứa. Chúng ta sẽ sử dụng các mã này bất cứ khi nào chúng ta muốn gửi hoặc truy xuất dữ liệu từ cơ sở dữ liệu. apiGet apiPost Chúng ta cần tạo cả tệp phẳng cơ sở dữ liệu và bảng để lưu trữ tất cả nội dung của chúng ta. Tạo đường dẫn tệp và thêm các mã bên dưới vào đó. Tập lệnh di chuyển cơ sở dữ liệu /frontend/app/api/migrations.ts https://Gist.github.com/Daltonic/4c213153fe53334fcf8444666587d6a5?embedable=true Mã này định nghĩa một hàm di chuyển cơ sở dữ liệu tạo ra một bảng 'movies' với các cột được chỉ định nếu nó không tồn tại, sử dụng SQLite và ghi lại kết quả của hoạt động. Bây giờ hãy chạy lệnh bên dưới trong một thiết bị đầu cuối trỏ đến thư mục . /frontend $ cd frontend $ npx esrun app/api/migrations.ts Cần lưu ý rằng quá trình này cũng sẽ tạo một tệp phẳng cơ sở dữ liệu có tên là tại thư mục gốc của frontend. Chúng tôi cũng đã thêm lệnh này vào tập lệnh package.json, do đó chạy trên thư mục frontend cũng sẽ hoạt động như vậy. movies.db $ yarn migrate Để dễ hình dung, hãy xem video bên dưới, chỉ cần dừng lại ở phút . 03:10:54 https://www.youtube.com/watch?v=ZJ8YWdVTWUA&t=10679&si=-uhv8Zw0T3Gx0XgQ&embedable=true Điểm cuối của ứng dụng Bây giờ, hãy định nghĩa một số điểm cuối để tạo, đọc, cập nhật và xóa phim. Chúng ta sẽ sử dụng quy định API NextJs để tạo các điểm cuối này. Để tạo phim, thông tin bắt buộc bao gồm ID người dùng, tên phim, hình ảnh, URL video, ngày phát hành, thể loại, xếp hạng, ngôn ngữ, thời lượng và mô tả bối cảnh. Tạo đường dẫn tệp và thêm các mã bên dưới vào đó. Tạo Điểm cuối Phim /frontend/app/api/movies/create/route.ts https://Gist.github.com/Daltonic/bf8a431ec00aa71491ae71781fb99278?embedable=true Mã này định nghĩa điểm cuối để xử lý các yêu cầu POST, xác thực và xử lý dữ liệu phim, tạo slug duy nhất và chèn dữ liệu vào cơ sở dữ liệu bằng hàm apiPost trong khi xử lý lỗi và trả về phản hồi JSON. Để cập nhật phim, thông tin bắt buộc bao gồm ID người dùng, slug và các thông tin khác được cung cấp khi tạo phim. Tạo đường dẫn tệp và thêm các mã bên dưới vào đó. Cập nhật Điểm cuối Phim /frontend/app/api/movies/update/route.ts https://Gist.github.com/Daltonic/2ed7d44cb8efe091675ebc0fc1bdf27c?embedable=true Mã này định nghĩa điểm cuối để xử lý các yêu cầu POST nhằm cập nhật phim, xác thực các thuộc tính cần thiết và thực thi truy vấn SQL để cập nhật dữ liệu phim trong cơ sở dữ liệu bằng hàm apiPost. Để xóa một bộ phim, thông tin bắt buộc bao gồm ID người dùng và slug của bộ phim. Tạo đường dẫn tệp và thêm các mã bên dưới vào đó. Xóa Điểm cuối Phim /frontend/app/api/movies/delete/route.ts https://Gist.github.com/Daltonic/aa7ab36b982ad1f377b2a4d26930dd8d?embedable=true Mã này định nghĩa điểm cuối để xử lý các yêu cầu POST nhằm xóa phim, xác thực các thuộc tính bắt buộc (userId và slug) và thực thi truy vấn SQL để xóa phim khỏi cơ sở dữ liệu bằng hàm apiPost. Dữ liệu tùy chọn cần thiết để lấy phim là pageSize và userId, có thể được truyền dưới dạng tham số truy vấn để lọc và phân trang kết quả. Tạo đường dẫn tệp và thêm các mã bên dưới vào đó. Tất cả các điểm cuối phim /frontend/app/api/movies/all/route.ts https://Gist.github.com/Daltonic/23bb2aa55446995dad87084bb7968c3e?embedable=true Đoạn mã trên định nghĩa điểm cuối để xử lý các yêu cầu GET nhằm truy xuất phim, cho phép lọc tùy chọn theo userId và phân trang theo pageSize, đồng thời trả về kết quả ở định dạng JSON. Để lấy một phim đơn lẻ, dữ liệu cần thiết là slug của phim. Tạo đường dẫn tệp và thêm các mã bên dưới vào đó. Điểm cuối phim đơn lẻ /frontend/app/api/movies/[slug]/route.ts https://Gist.github.com/Daltonic/64e069e9bafd026a83796eaa95334ac8?embedable=true Mã này định nghĩa điểm cuối để xử lý các yêu cầu GET nhằm truy xuất phim theo slug của phim đó, xác thực tham số slug và thực thi truy vấn SQL để truy xuất dữ liệu phim từ cơ sở dữ liệu bằng hàm apiGet. Đánh dấu tất cả các điểm cuối mà chúng ta sẽ cần cho ứng dụng này. Nếu bạn cần trợ giúp trực quan để giúp bạn hiểu rõ hơn về các điểm cuối này, vui lòng xem video bên dưới, chỉ cần đảm bảo bạn dừng lại ở mốc thời gian . 03:48:22 https://www.youtube.com/watch?v=ZJ8YWdVTWUA&t=10679&si=3Ynq9tNLx5SZXHBE&embedable=true Tích hợp điểm cuối Nhiệm vụ của chúng tôi là xem xét và cập nhật các thành phần và trang được mã hóa trước, giải thích mục đích và chức năng của từng thành phần và ghi lại các thay đổi chúng tôi thực hiện đối với mã hiện có. Chúng tôi sẽ bắt đầu bằng cách tạo một dịch vụ để tương tác với các điểm cuối mà chúng tôi đã tạo trước đó trong thư mục . api Tạo đường dẫn tệp và thêm đoạn mã bên dưới vào đó. /frontend/app/services/api.service.ts https://Gist.github.com/Daltonic/fdf65c7ffaf3ea8219c617cdb7c96375?embedable=true Dịch vụ này cung cấp một bộ chức năng để tương tác với cơ sở dữ liệu phim, cho phép ứng dụng tìm nạp phim, tìm nạp một phim duy nhất theo slug, tạo phim mới, cập nhật phim hiện có, xóa phim và tải tệp lên bằng cách sử dụng yêu cầu API và xử lý lỗi. Trang ứng dụng Hãy cùng xem xét và cập nhật các trang khác nhau liên quan đến ứng dụng của chúng tôi. Bạn không cần phải thay đổi nhiều thứ, chỉ cần những thứ được đánh dấu ở đây. Tạo trang phim Trang này là biểu mẫu xuất bản phim cho phép người dùng tải lên các tệp video và hình ảnh, nhập thông tin chi tiết về phim và gửi biểu mẫu để xuất bản phim, có xác thực và xử lý lỗi, sử dụng thư viện React và Wagmi. Bây giờ, hãy cập nhật tệp tìm thấy trong bằng mã bên dưới. /frontend/app/pages/create/page.tsx https://Gist.github.com/Daltonic/0ec440d6dfc2b46e07ecec3e81f532c6?embedable=true Những thay đổi được thực hiện trong đoạn mã này so với đoạn mã gốc là: Nhập hàm từ và sử dụng nó trong hàm để tạo phim mới. createMovie api.service handleSubmit Đã thêm tham số vào lệnh gọi hàm , truyền địa chỉ người dùng từ hook . userId createMovie useAccount Đã cập nhật hàm để sử dụng nhằm xử lý lời hứa được trả về bởi . handleSubmit toast.promise createMovie Đã thêm chức năng xử lý lỗi khi gọi hàm trong hàm . createMovie handleSubmit Những thay đổi này cho phép biểu mẫu gửi dữ liệu phim tới API và tạo mục phim mới đồng thời xử lý lỗi và hiển thị thông báo thành công. Chỉnh sửa trang phim Trang chỉnh sửa phim này cho phép người dùng được ủy quyền cập nhật thông tin chi tiết về phim, tải lên áp phích và video, cũng như lưu các thay đổi, với tính năng xác thực và xử lý lỗi, sử dụng React, Wagmi và Next.js, được thiết kế riêng để người dùng chỉnh sửa phim của họ. Bây giờ, hãy cập nhật tệp tìm thấy trong bằng mã bên dưới. /frontend/app/pages/movies/edit/[slug]/page.tsx https://Gist.github.com/Daltonic/63ddb6e3c65e3bcd2665ab0e3ffb6205?embedable=true Các nâng cấp được thực hiện cho mã khác với mã gốc là: Nhập các hàm và từ và sử dụng chúng trong hook và hàm . fetchMovie updateMovie @/app/services/api.service useEffect handleSubmit Thay thế phương thức bằng hàm để lấy dữ liệu phim. posters.find() fetchMovie Đã cập nhật hàm để gọi hàm với thông tin chi tiết về phim đã cập nhật. handleSubmit updateMovie Đã thêm chức năng xử lý lỗi vào lệnh gọi hàm trong hàm . updateMovie handleSubmit Những thay đổi này cho phép ứng dụng của chúng tôi tương tác với các điểm cuối API để truy xuất và cập nhật dữ liệu phim, trong khi mã gốc dựa vào mảng cục bộ của chúng tôi. posters Trang chủ Trang chủ này hiển thị thành phần biểu ngữ, danh sách phim (từ nguồn API hoặc giao diện người dùng đang tải) và các tùy chọn đăng ký, sử dụng React và Next.js để cung cấp trang đích hấp dẫn và nhiều thông tin cho người dùng. Cập nhật tệp tìm thấy trong bằng các mã sau. /frontend/app/pages/page.tsx https://Gist.github.com/Daltonic/97cb49662ed70be9b183b4f601b529d6?embedable=true Những thay đổi chúng tôi đã thực hiện trên trang chủ là: Nhập hàm từ và sử dụng hàm này trong hook để lấy dữ liệu phim từ API của chúng tôi. fetchMovies ./services/api.service useEffect Thay thế dữ liệu cục bộ bằng lệnh gọi hàm , hàm này sẽ lấy dữ liệu từ API của chúng tôi. posters fetchMovies Đã thêm từ khóa để chờ lời hứa trả về bởi giải quyết trước khi thiết lập trạng thái . await fetchMovies movies Những thay đổi này giúp ứng dụng của chúng tôi lấy dữ liệu phim từ API thay vì dựa vào dữ liệu cục bộ, giúp ứng dụng trở nên năng động hơn và dựa trên dữ liệu hơn. Trang tài khoản người dùng Trang này hiển thị danh sách các bộ phim do người dùng hiện đang kết nối đăng, với trình giữ chỗ khung tải trong khi dữ liệu đang được tải và thông báo nhắc người dùng kết nối tài khoản của họ nếu họ chưa thực hiện, bằng cách sử dụng Wagmi và react-loading-skeleton. Cập nhật tệp tìm thấy trong bằng các mã sau. /frontend/app/pages/account/page.tsx https://Gist.github.com/Daltonic/ba714bfa557f10aebacfa8b5ac3d7111?embedable=true Những thay đổi được thực hiện trên trang là: Nhập hàm từ và sử dụng hàm này trong hook để lấy dữ liệu phim từ API của chúng tôi. fetchMovies @/app/services/api.service useEffect Thay thế dữ liệu cục bộ bằng lệnh gọi hàm , hàm này sẽ lấy dữ liệu từ API của chúng tôi. posters fetchMovies Truyền làm đối số cho hàm để lấy dữ liệu phim dành riêng cho người dùng. address fetchMovies Đã xóa kiểm tra có điều kiện cho trước khi hiển thị danh sách phim vì hàm hiện xử lý logic này. address fetchMovies Đơn giản hóa câu lệnh điều kiện để hiển thị khung tải, vì bây giờ nó chỉ phụ thuộc vào trạng thái . loaded Những thay đổi này sẽ truy xuất dữ liệu phim từ API của chúng tôi, cụ thể cho người dùng được kết nối và hiển thị khung tải trong khi dữ liệu đang được truy xuất. Trang chi tiết phim Trang này hiển thị thông tin chi tiết của từng bộ phim, bao gồm tên, năm phát hành, xếp hạng, thời lượng, thể loại và thông tin cơ bản, cùng với trình phát video và các bộ phim liên quan, đồng thời cung cấp các tùy chọn để chỉnh sửa hoặc xóa phim nếu người dùng là chủ sở hữu, sử dụng Next.js và Wagmi. Cập nhật tệp tìm thấy trong bằng các mã sau. /frontend/app/pages/movies/[slug]/page.tsx https://Gist.github.com/Daltonic/5e37c94db3d73005a481ffd0cd141140?embedable=true Chúng tôi đã thực hiện một số thay đổi lớn ở đây! Sau đây là tóm tắt những gì chúng tôi đã làm: Nhập , và từ và sử dụng chúng để tương tác với các điểm cuối API của chúng tôi. deleteMovie fetchMovie fetchMovies @/app/services/api.service Thay thế dữ liệu cục bộ bằng lệnh gọi API để truy xuất dữ liệu phim. Đã triển khai chức năng xóa phim bằng hàm . deleteMovie Sử dụng để hiển thị thông báo khi xóa phim. toast.promise Đã xóa dữ liệu cục bộ và thay thế bằng lệnh gọi API. posters Đã cập nhật hàm để gọi hàm và xử lý phản hồi. handleSubmit deleteMovie Đã cập nhật hook để gọi các hàm và . useEffect fetchMovie fetchMovies Những thay đổi này khiến ứng dụng của chúng tôi tương tác với API để truy xuất và xóa dữ liệu phim và hiển thị thông báo cho người dùng trong quá trình xóa. Phần này của video bên dưới sẽ cho bạn thấy cách chúng tôi tích hợp các trang này với điểm cuối, vui lòng xem phần đó nếu bạn gặp bất kỳ vấn đề nào. Chỉ cần đảm bảo bạn dừng lại ở mốc thời gian . 04:57:41 https://www.youtube.com/watch?v=ZJ8YWdVTWUA&t=14070&si=XCKxX3HvX3RjtNHY&embedable=true Thành phần ứng dụng Hãy thảo luận về mục đích của từng thành phần trong ứng dụng của chúng ta. Chúng ta sẽ cập nhật bất kỳ thành phần nào cần sửa đổi. Thành phần biểu ngữ Thành phần này hiển thị hình nền xoay của biểu ngữ phim, tuần hoàn qua một mảng hình ảnh phim sau mỗi 5 giây, tạo hiệu ứng trình chiếu đơn giản và tự động. Mã thành phần này có thể được đánh giá tại . /frontend/app/components/home/Banner.tsx Thành phần Poster Thành phần này hiển thị một băng chuyền tương tác và phản hồi của các áp phích phim sử dụng thư viện Swiper, với các tính năng như tự động phát, phân trang và điều hướng, hiển thị danh sách các bộ phim được truyền dưới dạng prop, với bố cục động thích ứng với các kích thước màn hình khác nhau. Mã thành phần này có thể được đánh giá tại . /frontend/app/components/home/Posters.tsx Thành phần UI Poster Thành phần này hiển thị bố cục bộ xương giữ chỗ cho phần áp phích phim, sử dụng thư viện react-loading-skeleton, hiển thị số lượng bộ xương áp phích động dựa trên prop "posters", với thiết kế phản hồi thích ứng với các kích thước màn hình khác nhau, chỉ ra trạng thái tải cho đến khi dữ liệu áp phích thực tế được tải và hiển thị. Mã thành phần này có thể được đánh giá tại . /frontend/app/components/home/PosterUI.tsx Thành phần đăng ký Thành phần này hiển thị phần kế hoạch đăng ký, giới thiệu nhiều kế hoạch giả với thông tin chi tiết, giá cả và lợi ích của chúng. Nó cho phép người dùng chọn một kế hoạch phù hợp với nhu cầu của họ, sử dụng bố cục lưới phản hồi và hiệu ứng di chuột tương tác để nâng cao trải nghiệm của người dùng. Mã thành phần này có thể được đánh giá tại . /frontend/app/components/home/Subscription.tsx Thành phần tiêu đề Thành phần này tạo ra một thanh điều hướng cố định ở đầu trang, có logo, menu điều hướng với các liên kết đến nhiều phần khác nhau, nút chuyển đổi menu để thiết kế đáp ứng và nút đăng nhập, cung cấp phần tiêu đề nhất quán và dễ truy cập trên toàn bộ ứng dụng. Mã thành phần này có thể được đánh giá tại . /frontend/app/components/layout/Header.tsx Thành phần chân trang Thành phần này hiển thị phần chân trang ở cuối trang, có logo của ứng dụng, mô tả ngắn gọn, liên kết điều hướng, thông tin liên hệ và ghi nhận đề cập đến giải pháp lưu trữ phi tập trung do Sia Foundation cung cấp, cung cấp phần chân trang rõ ràng và có tổ chức với thông tin và liên kết có liên quan. Mã thành phần này có thể được đánh giá tại . /frontend/app/components/layout/Footer.tsx Thành phần Menu Thành phần này tạo ra một nút chuyển đổi menu phản hồi, khi nhấp vào, nút này sẽ mở hoặc đóng menu thả xuống chứa các liên kết điều hướng, cho phép người dùng truy cập nhiều phần khác nhau của ứng dụng trên màn hình nhỏ hơn trong khi ẩn menu trên màn hình lớn hơn nơi các liên kết điều hướng đã hiển thị. Mã thành phần này có thể được đánh giá tại . /frontend/app/components/shared/Menu.tsx Thành phần thẻ phim Thành phần này hiển thị áp phích của một bộ phim duy nhất với hiệu ứng di chuột, hiển thị thông tin bổ sung như tên phim, năm phát hành và tóm tắt bối cảnh đồng thời đóng vai trò là liên kết đến trang chi tiết của phim, sử dụng thiết kế phản hồi và chuyển tiếp hoạt hình để nâng cao trải nghiệm của người dùng. Mã thành phần này có thể được đánh giá tại . /frontend/app/components/shared/MovieCard.tsx Thành phần đã tải lên Thành phần này hiển thị bản xem trước của tệp đã tải lên, có thể là hình ảnh hoặc video, với thanh tiến trình và nút xóa, cho phép người dùng xem lại và xóa tệp đã tải lên, đồng thời cung cấp giao diện tương tác và hấp dẫn về mặt hình ảnh với hiệu ứng hoạt ảnh và di chuột qua. Mã thành phần này có thể được đánh giá tại . /frontend/app/components/shared/Uploaded.tsx Thành phần tải lên Thành phần này cung cấp giao diện người dùng để tải tệp lên, cụ thể là video hoặc áp phích, với các tính năng như kéo và thả, xác thực loại tệp, giới hạn kích thước, theo dõi tiến trình tải lên và thông báo thành công/lỗi, sử dụng kết hợp quản lý trạng thái React, xử lý sự kiện và tích hợp API để xử lý quy trình tải lên. Cập nhật tệp tìm thấy trong bằng các mã sau. /frontend/app/components/shared/uploader.tsx https://Gist.github.com/Daltonic/2aee8838dedcd6f14ef0f25103106a3a?embedable=true Những thay đổi được thực hiện đối với thành phần này là: : Mã gốc không có chức năng tải tệp lên thực tế. Mã này chỉ hiển thị thông báo toast thành công mà không tải tệp lên. Mã được cập nhật này bao gồm hàm từ xử lý việc tải tệp lên. Chức năng tải tệp lên uploadFile api.service : Mã được cập nhật sẽ theo dõi tiến trình tải lên và hiển thị trên UI. Theo dõi tiến trình : Mã được cập nhật bao gồm xử lý lỗi cho quá trình tải tệp lên. Xử lý lỗi : Mã được cập nhật sử dụng xác thực loại tệp mạnh mẽ hơn bằng cách sử dụng biểu thức chính quy. Xác thực loại tệp : Mã được cập nhật được tổ chức tốt hơn, với các chức năng riêng biệt để xử lý các tác vụ khác nhau, giúp dễ đọc và bảo trì hơn. Tổ chức mã : Mã cập nhật bao gồm một số cập nhật giao diện người dùng, chẳng hạn như hiển thị tiến trình tải lên và nút hủy trong quá trình tải lên. Cập nhật giao diện người dùng Mã cập nhật này hoàn thiện và mạnh mẽ hơn, có chức năng tải tệp thực tế, theo dõi tiến trình, xử lý lỗi và tổ chức mã tốt hơn. Video bên dưới giải thích chi tiết hơn về chức năng của từng thành phần, vui lòng xem để hiểu rõ hơn. https://www.youtube.com/watch?v=ZJ8YWdVTWUA&t=17861&si=LNxLwBkKeE7kH3Xt&embedable=true Và thế là xong các bạn, chúng ta đã hoàn thành dự án này, và bước cuối cùng chúng ta cần thực hiện là khởi chạy dự án này trên trình duyệt. Chạy để xem dự án trực tiếp trên trình duyệt. $ yarn build && yarn start Nếu bạn gặp bất kỳ vấn đề nào, hãy tham khảo các tài nguyên sau để khắc phục sự cố. Hẹn gặp lại lần sau, chúc bạn mọi điều tốt lành! 🏠 Trang web Sia 🔥 Sia Renterd 👨💻 Sia Renterd API 🚀 Kênh Discord của Sia 💡 Danh sách phát video YouTube Giới thiệu về tác giả Tôi là một nhà phát triển web3 và là người sáng lập , một công ty giúp các doanh nghiệp và cá nhân xây dựng và ra mắt các ứng dụng phi tập trung. Tôi có hơn 8 năm kinh nghiệm trong ngành phần mềm và tôi đam mê sử dụng công nghệ blockchain để tạo ra các ứng dụng mới và sáng tạo. Tôi điều hành một , nơi tôi chia sẻ các hướng dẫn và mẹo về phát triển web3 và tôi thường xuyên đăng các bài viết trực tuyến về các xu hướng mới nhất trong không gian blockchain. Dapp Mentors kênh YouTube có tên là Dapp Mentors