fix: 合集顺序播放

This commit is contained in:
guozhigq
2023-11-12 14:07:50 +08:00
parent c11c5695a2
commit 2ece96df21
7 changed files with 188 additions and 57 deletions

View File

@ -39,12 +39,25 @@ class SearchHttp {
static Future searchSuggest({required term}) async { static Future searchSuggest({required term}) async {
var res = await Request().get(Api.serachSuggest, var res = await Request().get(Api.serachSuggest,
data: {'term': term, 'main_ver': 'v1', 'highlight': term}); data: {'term': term, 'main_ver': 'v1', 'highlight': term});
if (res.data['code'] == 0) { if (res.data is String) {
res.data['result']['term'] = term; Map<String, dynamic> resultMap = json.decode(res.data);
return { if (resultMap['code'] == 0) {
'status': true, if (resultMap['result'] is Map) {
'data': SearchSuggestModel.fromJson(res.data['result']), resultMap['result']['term'] = term;
}; }
return {
'status': true,
'data': resultMap['result'] is Map
? SearchSuggestModel.fromJson(resultMap['result'])
: [],
};
} else {
return {
'status': false,
'data': [],
'msg': '请求错误 🙅',
};
}
} else { } else {
return { return {
'status': false, 'status': false,
@ -74,35 +87,44 @@ class SearchHttp {
var res = await Request().get(Api.searchByType, data: reqData); var res = await Request().get(Api.searchByType, data: reqData);
if (res.data['code'] == 0 && res.data['data']['numPages'] > 0) { if (res.data['code'] == 0 && res.data['data']['numPages'] > 0) {
Object data; Object data;
switch (searchType) { try {
case SearchType.video: switch (searchType) {
List<int> blackMidsList = case SearchType.video:
setting.get(SettingBoxKey.blackMidsList, defaultValue: [-1]); List<int> blackMidsList =
for (var i in res.data['data']['result']) { setting.get(SettingBoxKey.blackMidsList, defaultValue: [-1]);
// 屏蔽推广和拉黑用户 for (var i in res.data['data']['result']) {
i['available'] = !blackMidsList.contains(i['mid']); // 屏蔽推广和拉黑用户
} i['available'] = !blackMidsList.contains(i['mid']);
data = SearchVideoModel.fromJson(res.data['data']); }
break; data = SearchVideoModel.fromJson(res.data['data']);
// case SearchType.live_room: break;
// data = SearchLiveModel.fromJson(res.data['data']); case SearchType.live_room:
// break; data = SearchLiveModel.fromJson(res.data['data']);
case SearchType.bili_user: break;
data = SearchUserModel.fromJson(res.data['data']); case SearchType.bili_user:
break; data = SearchUserModel.fromJson(res.data['data']);
// case SearchType.media_bangumi: break;
// data = SearchMBangumiModel.fromJson(res.data['data']); case SearchType.media_bangumi:
// break; 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 { } else {
return { return {
'status': false, 'status': false,
'data': [], 'data': [],
'msg': res.data['data']['numPages'] == 0 ? '没有相关数据' : '请求错误 🙅', 'msg': res.data['data'] != null && res.data['data']['numPages'] == 0
? '没有相关数据'
: res.data['message'],
}; };
} }
} }

View File

@ -3,36 +3,29 @@ enum SearchType {
// 视频video // 视频video
video, video,
// 番剧media_bangumi, // 番剧media_bangumi,
// media_bangumi, media_bangumi,
// 影视media_ft // 影视media_ft
// media_ft, // media_ft,
// 直播间及主播live // 直播间及主播live
// live, // live,
// 直播间live_room // 直播间live_room
// live_room, live_room,
// 主播live_user // 主播live_user
// live_user, // live_user,
// 专栏article
// article,
// 话题topic // 话题topic
// topic, // topic,
// 用户bili_user // 用户bili_user
bili_user, bili_user,
// 专栏article
article,
// 相簿photo // 相簿photo
// photo // photo
} }
extension SearchTypeExtension on SearchType { extension SearchTypeExtension on SearchType {
String get type => [ String get type =>
'video', ['video', 'media_bangumi', 'live_room', 'bili_user', 'article'][index];
// 'media_bangumi', 'live_room', String get label => ['视频', '番剧', '直播间', '用户', '专栏'][index];
'bili_user'
][index];
String get label => [
'视频',
// '番剧', '直播间',
'用户'
][index];
} }
// 搜索类型为视频、专栏及相簿时 // 搜索类型为视频、专栏及相簿时
@ -40,17 +33,14 @@ enum ArchiveFilterType {
totalrank, totalrank,
click, click,
pubdate, pubdate,
// dm, dm,
// stow, stow,
// scores, scores,
// 专栏 // 专栏
// attention, // attention,
} }
extension ArchiveFilterTypeExtension on ArchiveFilterType { extension ArchiveFilterTypeExtension on ArchiveFilterType {
String get description => [ String get description =>
'默认排序', '播放多', '新发布', ['默认排序', '播放多', '新发布', '弹幕多', '收藏多', '评论多', '最多喜欢'][index];
// '弹幕多', '收藏多', '评论多',
'最多喜欢'
][index];
} }

View File

@ -378,3 +378,75 @@ class SearchMBangumiItemModel {
indexShow = json['index_show']; indexShow = json['index_show'];
} }
} }
class SearchArticleModel {
SearchArticleModel({this.list});
List<SearchArticleItemModel>? list;
SearchArticleModel.fromJson(Map<String, dynamic> json) {
list = json['result'] != null
? json['result']
.map<SearchArticleItemModel>(
(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<String, dynamic> 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'];
}
}

View File

@ -1,4 +1,6 @@
import 'dart:async'; import 'dart:async';
import 'dart:io';
import 'package:floating/floating.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart'; import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
import 'package:get/get.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/play/url.dart';
import 'package:pilipala/models/video/reply/item.dart'; import 'package:pilipala/models/video/reply/item.dart';
import 'package:pilipala/pages/video/detail/replyReply/index.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/plugin/pl_player/index.dart';
import 'package:pilipala/utils/storage.dart'; import 'package:pilipala/utils/storage.dart';
import 'package:pilipala/utils/utils.dart'; import 'package:pilipala/utils/utils.dart';
@ -76,6 +79,8 @@ class VideoDetailController extends GetxController
bool enableHeart = true; bool enableHeart = true;
var userInfo; var userInfo;
late bool isFirstTime = true; late bool isFirstTime = true;
Floating? floating;
late PreferredSizeWidget headerControl;
@override @override
void onInit() { void onInit() {
@ -104,6 +109,14 @@ class VideoDetailController extends GetxController
enableHeart = false; enableHeart = false;
} }
danmakuCid.value = cid.value; danmakuCid.value = cid.value;
if (Platform.isAndroid) {
floating = Floating();
}
headerControl = HeaderControl(
controller: plPlayerController,
videoDetailCtr: this,
floating: floating,
);
} }
showReplyReplyPanel() { showReplyReplyPanel() {

View File

@ -447,7 +447,7 @@ class VideoIntroController extends GetxController {
VideoDetailController videoDetailCtr = VideoDetailController videoDetailCtr =
Get.find<VideoDetailController>(tag: Get.arguments['heroTag']); Get.find<VideoDetailController>(tag: Get.arguments['heroTag']);
videoDetailCtr.bvid = bvid; videoDetailCtr.bvid = bvid;
videoDetailCtr.cid = cid; videoDetailCtr.cid.value = cid;
videoDetailCtr.danmakuCid.value = cid; videoDetailCtr.danmakuCid.value = cid;
videoDetailCtr.queryVideoUrl(); videoDetailCtr.queryVideoUrl();
// 重新请求评论 // 重新请求评论

View File

@ -1,6 +1,7 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:pilipala/models/video_detail_res.dart'; import 'package:pilipala/models/video_detail_res.dart';
import 'package:pilipala/pages/video/detail/index.dart';
import 'package:pilipala/utils/id_utils.dart'; import 'package:pilipala/utils/id_utils.dart';
class SeasonPanel extends StatefulWidget { class SeasonPanel extends StatefulWidget {
@ -23,11 +24,16 @@ class SeasonPanel extends StatefulWidget {
class _SeasonPanelState extends State<SeasonPanel> { class _SeasonPanelState extends State<SeasonPanel> {
late List<EpisodeItem> episodes; late List<EpisodeItem> episodes;
late int cid;
late int currentIndex; late int currentIndex;
String heroTag = Get.arguments['heroTag'];
late VideoDetailController _videoDetailController;
@override @override
void initState() { void initState() {
super.initState(); super.initState();
cid = widget.cid!;
_videoDetailController = Get.find<VideoDetailController>(tag: heroTag);
/// 根据 cid 找到对应集,找到对应 episodes /// 根据 cid 找到对应集,找到对应 episodes
/// 有多个episodes时只显示其中一个 /// 有多个episodes时只显示其中一个
@ -48,6 +54,11 @@ class _SeasonPanelState extends State<SeasonPanel> {
// .firstWhere((e) => e.seasonId == widget.ugcSeason.id) // .firstWhere((e) => e.seasonId == widget.ugcSeason.id)
// .episodes!; // .episodes!;
currentIndex = episodes.indexWhere((e) => e.cid == widget.cid); 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 { void changeFucCall(item, i) async {

View File

@ -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/introduction/index.dart';
import 'package:pilipala/pages/video/detail/related/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/index.dart';
import 'package:pilipala/plugin/pl_player/models/play_repeat.dart';
import 'package:pilipala/utils/storage.dart'; import 'package:pilipala/utils/storage.dart';
import 'widgets/app_bar.dart'; import 'widgets/app_bar.dart';
@ -54,6 +55,7 @@ class _VideoDetailPageState extends State<VideoDetailPage>
// 自动退出全屏 // 自动退出全屏
late bool autoExitFullcreen; late bool autoExitFullcreen;
Floating? floating; Floating? floating;
late BangumiIntroController bangumiIntroController;
@override @override
void initState() { void initState() {
@ -61,6 +63,7 @@ class _VideoDetailPageState extends State<VideoDetailPage>
heroTag = Get.arguments['heroTag']; heroTag = Get.arguments['heroTag'];
videoDetailController = Get.put(VideoDetailController(), tag: heroTag); videoDetailController = Get.put(VideoDetailController(), tag: heroTag);
videoIntroController = Get.put(VideoIntroController(), tag: heroTag); videoIntroController = Get.put(VideoIntroController(), tag: heroTag);
bangumiIntroController = Get.put(BangumiIntroController(), tag: heroTag);
statusBarHeight = localCache.get('statusBarHeight'); statusBarHeight = localCache.get('statusBarHeight');
autoExitFullcreen = autoExitFullcreen =
setting.get(SettingBoxKey.enableAutoExit, defaultValue: false); setting.get(SettingBoxKey.enableAutoExit, defaultValue: false);
@ -99,11 +102,31 @@ class _VideoDetailPageState extends State<VideoDetailPage>
if (autoExitFullcreen) { if (autoExitFullcreen) {
plPlayerController!.triggerFullScreen(status: false); plPlayerController!.triggerFullScreen(status: false);
} }
// 播放完展示控制栏
PiPStatus currentStatus = await floating!.pipStatus; /// 顺序播放 列表循环
if (currentStatus == PiPStatus.disabled) { if (plPlayerController!.playRepeat != PlayRepeat.pause &&
plPlayerController!.onLockControl(false); 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 (_) {}
} }
} }