diff --git a/lib/http/api.dart b/lib/http/api.dart index 4c378780..de89bee9 100644 --- a/lib/http/api.dart +++ b/lib/http/api.dart @@ -13,4 +13,7 @@ class Api { // 用户(被)关注数、投稿数 // https://api.bilibili.com/x/relation/stat?vmid=697166795 static const String userStat = '/x/relation/stat'; + + // 评论列表 + static const String replyList = '/x/v2/reply'; } diff --git a/lib/http/reply.dart b/lib/http/reply.dart new file mode 100644 index 00000000..1762ee4e --- /dev/null +++ b/lib/http/reply.dart @@ -0,0 +1,33 @@ +import 'package:pilipala/http/api.dart'; +import 'package:pilipala/http/init.dart'; + +class ReplyHttp { + static Future replyList({ + required String oid, + required int pageNum, + required int type, + int sort = 1, + }) async { + var res = await Request().get(Api.replyList, data: { + 'oid': oid, + 'pn': pageNum, + 'type': type, + 'sort': 1, + }); + print(res); + if (res.data['code'] == 0) { + } else { + Map errMap = { + -400: '请求错误', + -404: '无此项', + 12002: '评论区已关闭', + 12009: '评论主体的type不合法', + }; + return { + 'status': false, + 'date': [], + 'msg': errMap[res.data['code']] ?? '请求异常', + }; + } + } +} diff --git a/lib/http/user.dart b/lib/http/user.dart index 327f0ba5..ce3d4c43 100644 --- a/lib/http/user.dart +++ b/lib/http/user.dart @@ -2,7 +2,7 @@ import 'package:pilipala/http/api.dart'; import 'package:pilipala/http/init.dart'; class UserHttp { - static Future userStat(mid) async { + static Future userStat({required int mid}) async { var res = await Request().get(Api.userStat, data: {'vmid': mid}); if (res.data['code'] == 0) { return {'status': true, 'data': res.data['data']}; diff --git a/lib/http/video.dart b/lib/http/video.dart index b263f3ba..61f2770e 100644 --- a/lib/http/video.dart +++ b/lib/http/video.dart @@ -10,13 +10,13 @@ import 'package:pilipala/models/video_detail_res.dart'; /// view层根据 status 判断渲染逻辑 class VideoHttp { // 首页推荐视频 - static Future rcmdVideoList(data) async { + static Future rcmdVideoList({required int ps, required int freshIdx}) async { var res = await Request().get( Api.recommendList, data: { 'feed_version': 'V3', - 'ps': data['ps'], - 'fresh_idx': data['fresh_idx'] + 'ps': ps, + 'fresh_idx': freshIdx, }, ); if (res.data['code'] == 0) { @@ -31,13 +31,10 @@ class VideoHttp { } // 最热视频 - static Future hotVideoList(data) async { + static Future hotVideoList({required int pn, required int ps}) async { var res = await Request().get( Api.hotList, - data: { - 'pn': data['pn'], - 'ps': data['ps'], - }, + data: {'pn': pn, 'ps': ps}, ); if (res.data['code'] == 0) { List list = []; @@ -51,7 +48,7 @@ class VideoHttp { } // 视频信息 标题、简介 - static Future videoIntro(aid) async { + static Future videoIntro({required String aid}) async { var res = await Request().get(Api.videoIntro, data: {'aid': aid}); VideoDetailResponse result = VideoDetailResponse.fromJson(res.data); if (result.code == 0) { @@ -67,13 +64,13 @@ class VideoHttp { return { 'status': false, 'data': null, - 'msg': errMap[result.code] ?? '请求异常' + 'msg': errMap[result.code] ?? '请求异常', }; } } // 相关视频 - static Future relatedVideoList(aid) async { + static Future relatedVideoList({required String aid}) async { var res = await Request().get(Api.relatedList, data: {'aid': aid}); if (res.data['code'] == 0) { List list = []; diff --git a/lib/pages/home/controller.dart b/lib/pages/home/controller.dart index 809eda17..e96d8b60 100644 --- a/lib/pages/home/controller.dart +++ b/lib/pages/home/controller.dart @@ -20,10 +20,10 @@ class HomeController extends GetxController { // 获取推荐 Future queryRcmdFeed(type) async { - var res = await VideoHttp.rcmdVideoList({ - 'ps': count, - 'fresh_idx': _currentPage, - }); + var res = await VideoHttp.rcmdVideoList( + ps: count, + freshIdx: _currentPage, + ); if (res['status']) { if (type == 'init') { videoList.value = res['data']; diff --git a/lib/pages/hot/controller.dart b/lib/pages/hot/controller.dart index 3690b9e9..0620ecf4 100644 --- a/lib/pages/hot/controller.dart +++ b/lib/pages/hot/controller.dart @@ -19,10 +19,10 @@ class HotController extends GetxController { // 获取推荐 Future queryHotFeed(type) async { - var res = await VideoHttp.hotVideoList({ - 'pn': _currentPage, - 'ps': _count, - }); + var res = await VideoHttp.hotVideoList( + pn: _currentPage, + ps: _count, + ); if (res['status']) { if (type == 'init') { videoList.value = res['data']; diff --git a/lib/pages/video/detail/controller.dart b/lib/pages/video/detail/controller.dart index 89142e01..744c6c74 100644 --- a/lib/pages/video/detail/controller.dart +++ b/lib/pages/video/detail/controller.dart @@ -1,6 +1,7 @@ import 'package:get/get.dart'; class VideoDetailController extends GetxController { + int tabInitialIndex = 0; // tabs RxList tabs = ['简介', '评论'].obs; diff --git a/lib/pages/video/detail/introduction/controller.dart b/lib/pages/video/detail/introduction/controller.dart index d3740d05..4c1b7522 100644 --- a/lib/pages/video/detail/introduction/controller.dart +++ b/lib/pages/video/detail/introduction/controller.dart @@ -44,7 +44,7 @@ class VideoIntroController extends GetxController { // 获取视频简介 Future queryVideoIntro() async { - var result = await VideoHttp.videoIntro(aid); + var result = await VideoHttp.videoIntro(aid: aid); if (result['status']) { videoDetail.value = result['data']!; Get.find().tabs.value = [ @@ -61,7 +61,7 @@ class VideoIntroController extends GetxController { // 获取up主粉丝数 Future queryUserStat() async { - var result = await UserHttp.userStat(videoDetail.value.owner!.mid); + var result = await UserHttp.userStat(mid: videoDetail.value.owner!.mid!); if (result['status']) { userStat = result['data']; } diff --git a/lib/pages/video/detail/related/controller.dart b/lib/pages/video/detail/related/controller.dart index ed9cad3a..cb9081dc 100644 --- a/lib/pages/video/detail/related/controller.dart +++ b/lib/pages/video/detail/related/controller.dart @@ -7,5 +7,5 @@ class ReleatedController extends GetxController { // 推荐视频列表 List relatedVideoList = []; - Future queryRelatedVideo() => VideoHttp.relatedVideoList(aid); + Future queryRelatedVideo() => VideoHttp.relatedVideoList(aid: aid); } diff --git a/lib/pages/video/detail/reply/controller.dart b/lib/pages/video/detail/reply/controller.dart new file mode 100644 index 00000000..d18a74b2 --- /dev/null +++ b/lib/pages/video/detail/reply/controller.dart @@ -0,0 +1,17 @@ +import 'package:get/get.dart'; +import 'package:pilipala/http/reply.dart'; + +class VideoReplyController extends GetxController { + // 视频aid + String aid = Get.parameters['aid']!; + + @override + void onInit() { + super.onInit(); + queryReplyList(); + } + + Future queryReplyList() async { + var res = await ReplyHttp.replyList(oid: aid, pageNum: 1, type: 1); + } +} diff --git a/lib/pages/video/detail/reply/index.dart b/lib/pages/video/detail/reply/index.dart new file mode 100644 index 00000000..f3d25ba4 --- /dev/null +++ b/lib/pages/video/detail/reply/index.dart @@ -0,0 +1,4 @@ +library video_reply_panel; + +export './controller.dart'; +export './view.dart'; diff --git a/lib/pages/video/detail/reply/view.dart b/lib/pages/video/detail/reply/view.dart new file mode 100644 index 00000000..13661065 --- /dev/null +++ b/lib/pages/video/detail/reply/view.dart @@ -0,0 +1,17 @@ +import 'package:flutter/material.dart'; + +class VideoReplyPanel extends StatefulWidget { + const VideoReplyPanel({super.key}); + + @override + State createState() => _VideoReplyPanelState(); +} + +class _VideoReplyPanelState extends State { + @override + Widget build(BuildContext context) { + return const SliverToBoxAdapter( + child: Text('评论'), + ); + } +} diff --git a/lib/pages/video/detail/view.dart b/lib/pages/video/detail/view.dart index eb088f19..78beb58b 100644 --- a/lib/pages/video/detail/view.dart +++ b/lib/pages/video/detail/view.dart @@ -1,6 +1,7 @@ import 'package:get/get.dart'; import 'package:flutter/material.dart'; import 'package:pilipala/common/widgets/network_img_layer.dart'; +import 'package:pilipala/pages/video/detail/reply/index.dart'; import 'package:pilipala/pages/video/detail/controller.dart'; import 'package:pilipala/pages/video/detail/introduction/index.dart'; import 'package:pilipala/pages/video/detail/related/index.dart'; @@ -19,6 +20,7 @@ class _VideoDetailPageState extends State { @override Widget build(BuildContext context) { return DefaultTabController( + initialIndex: videoDetailController.tabInitialIndex, length: videoDetailController.tabs.length, // tab的数量. child: SafeArea( top: false, @@ -137,9 +139,7 @@ class _VideoDetailPageState extends State { handle: NestedScrollView.sliverOverlapAbsorberHandleFor( context), ), - const SliverToBoxAdapter( - child: Text('评论'), - ) + const VideoReplyPanel() ], ); })