From 2ece96df217011b8e022c547af532a06f19bc057 Mon Sep 17 00:00:00 2001 From: guozhigq Date: Sun, 12 Nov 2023 14:07:50 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E5=90=88=E9=9B=86=E9=A1=BA=E5=BA=8F?= =?UTF-8?q?=E6=92=AD=E6=94=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/http/search.dart | 82 ++++++++++++------- lib/models/common/search_type.dart | 34 +++----- lib/models/search/result.dart | 72 ++++++++++++++++ lib/pages/video/detail/controller.dart | 13 +++ .../video/detail/introduction/controller.dart | 2 +- .../detail/introduction/widgets/season.dart | 11 +++ lib/pages/video/detail/view.dart | 31 ++++++- 7 files changed, 188 insertions(+), 57 deletions(-) diff --git a/lib/http/search.dart b/lib/http/search.dart index c9a7eb38..b94ace2c 100644 --- a/lib/http/search.dart +++ b/lib/http/search.dart @@ -39,12 +39,25 @@ class SearchHttp { static Future searchSuggest({required term}) async { var res = await Request().get(Api.serachSuggest, data: {'term': term, 'main_ver': 'v1', 'highlight': term}); - if (res.data['code'] == 0) { - res.data['result']['term'] = term; - return { - 'status': true, - 'data': SearchSuggestModel.fromJson(res.data['result']), - }; + if (res.data is String) { + Map resultMap = json.decode(res.data); + if (resultMap['code'] == 0) { + if (resultMap['result'] is Map) { + resultMap['result']['term'] = term; + } + return { + 'status': true, + 'data': resultMap['result'] is Map + ? SearchSuggestModel.fromJson(resultMap['result']) + : [], + }; + } else { + return { + 'status': false, + 'data': [], + 'msg': '请求错误 🙅', + }; + } } else { return { 'status': false, @@ -74,35 +87,44 @@ class SearchHttp { var res = await Request().get(Api.searchByType, data: reqData); if (res.data['code'] == 0 && res.data['data']['numPages'] > 0) { Object data; - switch (searchType) { - case SearchType.video: - List blackMidsList = - setting.get(SettingBoxKey.blackMidsList, defaultValue: [-1]); - for (var i in res.data['data']['result']) { - // 屏蔽推广和拉黑用户 - i['available'] = !blackMidsList.contains(i['mid']); - } - data = SearchVideoModel.fromJson(res.data['data']); - break; - // case SearchType.live_room: - // data = SearchLiveModel.fromJson(res.data['data']); - // break; - case SearchType.bili_user: - data = SearchUserModel.fromJson(res.data['data']); - break; - // case SearchType.media_bangumi: - // data = SearchMBangumiModel.fromJson(res.data['data']); - // break; + try { + switch (searchType) { + case SearchType.video: + List blackMidsList = + setting.get(SettingBoxKey.blackMidsList, defaultValue: [-1]); + for (var i in res.data['data']['result']) { + // 屏蔽推广和拉黑用户 + i['available'] = !blackMidsList.contains(i['mid']); + } + data = SearchVideoModel.fromJson(res.data['data']); + break; + case SearchType.live_room: + data = SearchLiveModel.fromJson(res.data['data']); + break; + case SearchType.bili_user: + data = SearchUserModel.fromJson(res.data['data']); + break; + case SearchType.media_bangumi: + data = SearchMBangumiModel.fromJson(res.data['data']); + break; + case SearchType.article: + data = SearchArticleModel.fromJson(res.data['data']); + break; + } + return { + 'status': true, + 'data': data, + }; + } catch (err) { + print(err); } - return { - 'status': true, - 'data': data, - }; } else { return { 'status': false, 'data': [], - 'msg': res.data['data']['numPages'] == 0 ? '没有相关数据' : '请求错误 🙅', + 'msg': res.data['data'] != null && res.data['data']['numPages'] == 0 + ? '没有相关数据' + : res.data['message'], }; } } diff --git a/lib/models/common/search_type.dart b/lib/models/common/search_type.dart index 3d9f4c48..d7d13aec 100644 --- a/lib/models/common/search_type.dart +++ b/lib/models/common/search_type.dart @@ -3,36 +3,29 @@ enum SearchType { // 视频:video video, // 番剧:media_bangumi, - // media_bangumi, + media_bangumi, // 影视:media_ft // media_ft, // 直播间及主播:live // live, // 直播间:live_room - // live_room, + live_room, // 主播:live_user // live_user, - // 专栏:article - // article, // 话题:topic // topic, // 用户:bili_user bili_user, + // 专栏:article + article, // 相簿:photo // photo } extension SearchTypeExtension on SearchType { - String get type => [ - 'video', - // 'media_bangumi', 'live_room', - 'bili_user' - ][index]; - String get label => [ - '视频', - // '番剧', '直播间', - '用户' - ][index]; + String get type => + ['video', 'media_bangumi', 'live_room', 'bili_user', 'article'][index]; + String get label => ['视频', '番剧', '直播间', '用户', '专栏'][index]; } // 搜索类型为视频、专栏及相簿时 @@ -40,17 +33,14 @@ enum ArchiveFilterType { totalrank, click, pubdate, - // dm, - // stow, - // scores, + dm, + stow, + scores, // 专栏 // attention, } extension ArchiveFilterTypeExtension on ArchiveFilterType { - String get description => [ - '默认排序', '播放多', '新发布', - // '弹幕多', '收藏多', '评论多', - '最多喜欢' - ][index]; + String get description => + ['默认排序', '播放多', '新发布', '弹幕多', '收藏多', '评论多', '最多喜欢'][index]; } diff --git a/lib/models/search/result.dart b/lib/models/search/result.dart index 72b9cd92..3d381ed9 100644 --- a/lib/models/search/result.dart +++ b/lib/models/search/result.dart @@ -378,3 +378,75 @@ class SearchMBangumiItemModel { indexShow = json['index_show']; } } + +class SearchArticleModel { + SearchArticleModel({this.list}); + + List? list; + + SearchArticleModel.fromJson(Map json) { + list = json['result'] != null + ? json['result'] + .map( + (e) => SearchArticleItemModel.fromJson(e)) + .toList() + : []; + } +} + +class SearchArticleItemModel { + SearchArticleItemModel({ + this.pubTime, + this.like, + this.title, + this.subTitle, + this.rankOffset, + this.mid, + this.imageUrls, + this.id, + this.categoryId, + this.view, + this.reply, + this.desc, + this.rankScore, + this.type, + this.templateId, + this.categoryName, + }); + + int? pubTime; + int? like; + List? title; + String? subTitle; + int? rankOffset; + int? mid; + List? imageUrls; + int? id; + int? categoryId; + int? view; + int? reply; + String? desc; + int? rankScore; + String? type; + int? templateId; + String? categoryName; + + SearchArticleItemModel.fromJson(Map json) { + pubTime = json['pub_time']; + like = json['like']; + title = Em.regTitle(json['title']); + subTitle = json['title'].replaceAll(RegExp(r'<[^>]*>'), ''); + rankOffset = json['rank_offset']; + mid = json['mid']; + imageUrls = json['image_urls']; + id = json['id']; + categoryId = json['category_id']; + view = json['view']; + reply = json['reply']; + desc = json['desc']; + rankScore = json['rank_score']; + type = json['type']; + templateId = json['templateId']; + categoryName = json['category_name']; + } +} diff --git a/lib/pages/video/detail/controller.dart b/lib/pages/video/detail/controller.dart index 86b10f80..469b2b97 100644 --- a/lib/pages/video/detail/controller.dart +++ b/lib/pages/video/detail/controller.dart @@ -1,4 +1,6 @@ import 'dart:async'; +import 'dart:io'; +import 'package:floating/floating.dart'; import 'package:flutter/material.dart'; import 'package:flutter_smart_dialog/flutter_smart_dialog.dart'; import 'package:get/get.dart'; @@ -11,6 +13,7 @@ import 'package:pilipala/models/video/play/quality.dart'; import 'package:pilipala/models/video/play/url.dart'; import 'package:pilipala/models/video/reply/item.dart'; import 'package:pilipala/pages/video/detail/replyReply/index.dart'; +import 'package:pilipala/pages/video/detail/widgets/header_control.dart'; import 'package:pilipala/plugin/pl_player/index.dart'; import 'package:pilipala/utils/storage.dart'; import 'package:pilipala/utils/utils.dart'; @@ -76,6 +79,8 @@ class VideoDetailController extends GetxController bool enableHeart = true; var userInfo; late bool isFirstTime = true; + Floating? floating; + late PreferredSizeWidget headerControl; @override void onInit() { @@ -104,6 +109,14 @@ class VideoDetailController extends GetxController enableHeart = false; } danmakuCid.value = cid.value; + if (Platform.isAndroid) { + floating = Floating(); + } + headerControl = HeaderControl( + controller: plPlayerController, + videoDetailCtr: this, + floating: floating, + ); } showReplyReplyPanel() { diff --git a/lib/pages/video/detail/introduction/controller.dart b/lib/pages/video/detail/introduction/controller.dart index b72fbd74..5eb01e22 100644 --- a/lib/pages/video/detail/introduction/controller.dart +++ b/lib/pages/video/detail/introduction/controller.dart @@ -447,7 +447,7 @@ class VideoIntroController extends GetxController { VideoDetailController videoDetailCtr = Get.find(tag: Get.arguments['heroTag']); videoDetailCtr.bvid = bvid; - videoDetailCtr.cid = cid; + videoDetailCtr.cid.value = cid; videoDetailCtr.danmakuCid.value = cid; videoDetailCtr.queryVideoUrl(); // 重新请求评论 diff --git a/lib/pages/video/detail/introduction/widgets/season.dart b/lib/pages/video/detail/introduction/widgets/season.dart index 3f3a1475..c02b8dc6 100644 --- a/lib/pages/video/detail/introduction/widgets/season.dart +++ b/lib/pages/video/detail/introduction/widgets/season.dart @@ -1,6 +1,7 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:pilipala/models/video_detail_res.dart'; +import 'package:pilipala/pages/video/detail/index.dart'; import 'package:pilipala/utils/id_utils.dart'; class SeasonPanel extends StatefulWidget { @@ -23,11 +24,16 @@ class SeasonPanel extends StatefulWidget { class _SeasonPanelState extends State { late List episodes; + late int cid; late int currentIndex; + String heroTag = Get.arguments['heroTag']; + late VideoDetailController _videoDetailController; @override void initState() { super.initState(); + cid = widget.cid!; + _videoDetailController = Get.find(tag: heroTag); /// 根据 cid 找到对应集,找到对应 episodes /// 有多个episodes时,只显示其中一个 @@ -48,6 +54,11 @@ class _SeasonPanelState extends State { // .firstWhere((e) => e.seasonId == widget.ugcSeason.id) // .episodes!; currentIndex = episodes.indexWhere((e) => e.cid == widget.cid); + _videoDetailController.cid.listen((p0) { + cid = p0; + setState(() {}); + currentIndex = episodes.indexWhere((e) => e.cid == cid); + }); } void changeFucCall(item, i) async { diff --git a/lib/pages/video/detail/view.dart b/lib/pages/video/detail/view.dart index cc1d577b..2b2774ff 100644 --- a/lib/pages/video/detail/view.dart +++ b/lib/pages/video/detail/view.dart @@ -20,6 +20,7 @@ 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'; import 'package:pilipala/plugin/pl_player/index.dart'; +import 'package:pilipala/plugin/pl_player/models/play_repeat.dart'; import 'package:pilipala/utils/storage.dart'; import 'widgets/app_bar.dart'; @@ -54,6 +55,7 @@ class _VideoDetailPageState extends State // 自动退出全屏 late bool autoExitFullcreen; Floating? floating; + late BangumiIntroController bangumiIntroController; @override void initState() { @@ -61,6 +63,7 @@ class _VideoDetailPageState extends State heroTag = Get.arguments['heroTag']; videoDetailController = Get.put(VideoDetailController(), tag: heroTag); videoIntroController = Get.put(VideoIntroController(), tag: heroTag); + bangumiIntroController = Get.put(BangumiIntroController(), tag: heroTag); statusBarHeight = localCache.get('statusBarHeight'); autoExitFullcreen = setting.get(SettingBoxKey.enableAutoExit, defaultValue: false); @@ -99,11 +102,31 @@ class _VideoDetailPageState extends State if (autoExitFullcreen) { plPlayerController!.triggerFullScreen(status: false); } - // 播放完展示控制栏 - PiPStatus currentStatus = await floating!.pipStatus; - if (currentStatus == PiPStatus.disabled) { - plPlayerController!.onLockControl(false); + + /// 顺序播放 列表循环 + if (plPlayerController!.playRepeat != PlayRepeat.pause && + plPlayerController!.playRepeat != PlayRepeat.singleCycle) { + if (videoDetailController.videoType == SearchType.video) { + videoIntroController.nextPlay(); + } + if (videoDetailController.videoType == SearchType.media_bangumi) { + bangumiIntroController.nextPlay(); + } } + + /// 单个循环 + if (plPlayerController!.playRepeat == PlayRepeat.singleCycle) { + plPlayerController!.seekTo(Duration.zero); + plPlayerController!.play(); + } + // 播放完展示控制栏 + try { + PiPStatus currentStatus = + await videoDetailController.floating!.pipStatus; + if (currentStatus == PiPStatus.disabled) { + plPlayerController!.onLockControl(false); + } + } catch (_) {} } }