opt: play all

Signed-off-by: bggRGjQaUbCoE <githubaccount56556@proton.me>
This commit is contained in:
bggRGjQaUbCoE
2024-12-25 18:10:57 +08:00
parent 234017cc8a
commit 11dde3a887
4 changed files with 55 additions and 57 deletions

View File

@@ -1,68 +1,50 @@
import 'package:PiliPalaX/common/widgets/stat/danmu.dart'; import 'package:PiliPalaX/common/widgets/stat/danmu.dart';
import 'package:PiliPalaX/common/widgets/stat/view.dart'; import 'package:PiliPalaX/common/widgets/stat/view.dart';
import 'package:PiliPalaX/utils/extension.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:PiliPalaX/common/constants.dart'; import 'package:PiliPalaX/common/constants.dart';
import 'package:PiliPalaX/common/widgets/badge.dart'; import 'package:PiliPalaX/common/widgets/badge.dart';
import 'package:PiliPalaX/common/widgets/network_img_layer.dart'; import 'package:PiliPalaX/common/widgets/network_img_layer.dart';
import 'package:PiliPalaX/http/search.dart'; import 'package:PiliPalaX/http/search.dart';
import 'package:PiliPalaX/http/user.dart';
import 'package:PiliPalaX/models/video/later.dart'; import 'package:PiliPalaX/models/video/later.dart';
import 'package:PiliPalaX/utils/utils.dart'; import 'package:PiliPalaX/utils/utils.dart';
import 'package:scrollable_positioned_list/scrollable_positioned_list.dart';
class MediaListPanel extends StatefulWidget { class MediaListPanel extends StatefulWidget {
const MediaListPanel({ const MediaListPanel({
this.sheetHeight,
required this.mediaList, required this.mediaList,
this.changeMediaList, this.changeMediaList,
this.panelTitle, this.panelTitle,
this.bvid, this.bvid,
this.mediaId,
this.hasMore = false, this.hasMore = false,
required this.loadMoreMedia,
super.key, super.key,
}); });
final double? sheetHeight;
final List<MediaVideoItemModel> mediaList; final List<MediaVideoItemModel> mediaList;
final Function? changeMediaList; final Function? changeMediaList;
final String? panelTitle; final String? panelTitle;
final String? bvid; final String? bvid;
final int? mediaId;
final bool hasMore; final bool hasMore;
final VoidCallback loadMoreMedia;
@override @override
State<MediaListPanel> createState() => _MediaListPanelState(); State<MediaListPanel> createState() => _MediaListPanelState();
} }
class _MediaListPanelState extends State<MediaListPanel> { class _MediaListPanelState extends State<MediaListPanel> {
RxList<MediaVideoItemModel> mediaList = <MediaVideoItemModel>[].obs; final _scrollController = ItemScrollController();
bool _isEnd = false;
@override @override
void initState() { void initState() {
super.initState(); super.initState();
mediaList.value = widget.mediaList; WidgetsBinding.instance.addPostFrameCallback((_) {
_isEnd = widget.hasMore.not; int index =
} widget.mediaList.indexWhere((item) => item.bvid == widget.bvid);
if (index != -1 && index != 0) {
void loadMore() async { _scrollController.jumpTo(index: index);
var res = await UserHttp.getMediaList(
type: 3,
bizId: widget.mediaId ?? -1,
ps: 20,
oid: mediaList.last.id,
);
if (res['status']) {
if (res['data'].isNotEmpty) {
mediaList.addAll(res['data']);
} else {
_isEnd = true;
} }
} else { });
SmartDialog.showToast(res['msg']);
}
} }
@override @override
@@ -90,12 +72,14 @@ class _MediaListPanelState extends State<MediaListPanel> {
child: Material( child: Material(
color: Theme.of(context).colorScheme.surface, color: Theme.of(context).colorScheme.surface,
child: Obx( child: Obx(
() => ListView.builder( () => ScrollablePositionedList.builder(
itemCount: mediaList.length, itemScrollController: _scrollController,
itemCount: widget.mediaList.length,
itemBuilder: ((context, index) { itemBuilder: ((context, index) {
var item = mediaList[index]; var item = widget.mediaList[index];
if (index == widget.mediaList.length - 1 && _isEnd.not) { if (index == widget.mediaList.length - 1 &&
loadMore(); widget.hasMore) {
widget.loadMoreMedia();
} }
return InkWell( return InkWell(
onTap: () async { onTap: () async {

View File

@@ -55,7 +55,6 @@ class MediaVideoItemModel {
int? type; int? type;
Upper? upper; Upper? upper;
String? link; String? link;
String? bvId;
String? shortLink; String? shortLink;
Rights? rights; Rights? rights;
dynamic elecInfo; dynamic elecInfo;

View File

@@ -24,7 +24,6 @@ import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.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';
import 'package:hive/hive.dart';
import 'package:PiliPalaX/http/constants.dart'; import 'package:PiliPalaX/http/constants.dart';
import 'package:PiliPalaX/http/video.dart'; import 'package:PiliPalaX/http/video.dart';
import 'package:PiliPalaX/models/common/search_type.dart'; import 'package:PiliPalaX/models/common/search_type.dart';
@@ -183,11 +182,6 @@ class VideoDetailController extends GetxController
RxBool enableHA = true.obs; RxBool enableHA = true.obs;
RxString hwdec = 'auto-safe'.obs; RxString hwdec = 'auto-safe'.obs;
/// 本地存储
Box userInfoCache = GStorage.userInfo;
Box localCache = GStorage.localCache;
Box setting = GStorage.setting;
RxInt oid = 0.obs; RxInt oid = 0.obs;
final scaffoldKey = GlobalKey<ScaffoldState>(); final scaffoldKey = GlobalKey<ScaffoldState>();
@@ -247,36 +241,35 @@ class VideoDetailController extends GetxController
// 页面来源 稍后再看 收藏夹 // 页面来源 稍后再看 收藏夹
RxString sourceType = 'normal'.obs; RxString sourceType = 'normal'.obs;
List<MediaVideoItemModel> mediaList = <MediaVideoItemModel>[]; late RxList<MediaVideoItemModel> mediaList = <MediaVideoItemModel>[].obs;
RxString watchLaterTitle = ''.obs; late RxString watchLaterTitle = ''.obs;
bool get isPlayAll => bool get isPlayAll =>
sourceType.value == 'watchLater' || sourceType.value == 'fav'; sourceType.value == 'watchLater' || sourceType.value == 'fav';
@override @override
void onInit() { void onInit() {
super.onInit(); super.onInit();
final Map argMap = Get.arguments; userInfo = GStorage.userInfo.get('userInfoCache');
userInfo = userInfoCache.get('userInfoCache'); var keys = Get.arguments.keys.toList();
var keys = argMap.keys.toList();
if (keys.isNotEmpty) { if (keys.isNotEmpty) {
if (keys.contains('videoItem')) { if (keys.contains('videoItem')) {
var args = argMap['videoItem']; var args = Get.arguments['videoItem'];
if (args.pic != null && args.pic != '') { if (args.pic != null && args.pic != '') {
videoItem['pic'] = args.pic; videoItem['pic'] = args.pic;
} }
} }
if (keys.contains('pic')) { if (keys.contains('pic')) {
videoItem['pic'] = argMap['pic']; videoItem['pic'] = Get.arguments['pic'];
} }
} }
sourceType.value = argMap['sourceType'] ?? 'normal'; sourceType.value = Get.arguments['sourceType'] ?? 'normal';
if (sourceType.value == 'watchLater') { if (sourceType.value == 'watchLater') {
watchLaterTitle.value = '稍后再看'; watchLaterTitle.value = '稍后再看';
fetchMediaList(); fetchMediaList();
} else if (sourceType.value == 'fav') { } else if (sourceType.value == 'fav') {
watchLaterTitle.value = argMap['favTitle']; watchLaterTitle.value = Get.arguments['favTitle'];
queryFavVideoList(); queryFavVideoList();
} }
@@ -332,8 +325,7 @@ class VideoDetailController extends GetxController
// 获取稍后再看列表 // 获取稍后再看列表
Future fetchMediaList() async { Future fetchMediaList() async {
final Map argMap = Get.arguments; var count = Get.arguments['count'];
var count = argMap['count'];
var res = await UserHttp.getMediaList( var res = await UserHttp.getMediaList(
type: 2, type: 2,
bizId: userInfo.mid, bizId: userInfo.mid,
@@ -346,6 +338,25 @@ class VideoDetailController extends GetxController
} }
} }
void loadMoreMedia() async {
if (mediaList.length >= Get.arguments['count']) {
return;
}
var res = await UserHttp.getMediaList(
type: 3,
bizId: Get.arguments['mediaId'] ?? -1,
ps: 20,
oid: mediaList.last.id,
);
if (res['status']) {
if (res['data'].isNotEmpty) {
mediaList.addAll(res['data']);
}
} else {
SmartDialog.showToast(res['msg']);
}
}
// 稍后再看面板展开 // 稍后再看面板展开
showMediaListPanel() { showMediaListPanel() {
if (mediaList.isNotEmpty) { if (mediaList.isNotEmpty) {
@@ -355,8 +366,8 @@ class VideoDetailController extends GetxController
changeMediaList: changeMediaList, changeMediaList: changeMediaList,
panelTitle: watchLaterTitle.value, panelTitle: watchLaterTitle.value,
bvid: bvid, bvid: bvid,
mediaId: Get.arguments['mediaId'], hasMore: mediaList.length < Get.arguments['count'],
hasMore: mediaList.length != Get.arguments['count'], loadMoreMedia: loadMoreMedia,
), ),
); );
} }
@@ -393,16 +404,15 @@ class VideoDetailController extends GetxController
// 获取收藏夹视频列表 // 获取收藏夹视频列表
Future queryFavVideoList() async { Future queryFavVideoList() async {
final Map argMap = Get.arguments; var mediaId = Get.arguments['mediaId'];
var mediaId = argMap['mediaId']; var oid = Get.arguments['oid'];
var oid = argMap['oid'];
var res = await UserHttp.parseFavVideo( var res = await UserHttp.parseFavVideo(
mediaId: mediaId, mediaId: mediaId,
oid: oid, oid: oid,
bvid: bvid, bvid: bvid,
); );
if (res['status']) { if (res['status']) {
mediaList = res['data']; mediaList.value = res['data'];
} }
} }

View File

@@ -691,6 +691,11 @@ class VideoIntroController extends GetxController
episodes.indexWhere((e) => e.cid == lastPlayCid.value); episodes.indexWhere((e) => e.cid == lastPlayCid.value);
int nextIndex = currentIndex + 1; int nextIndex = currentIndex + 1;
if (videoDetailController.isPlayAll &&
currentIndex == episodes.length - 2) {
videoDetailCtr.loadMoreMedia();
}
// 列表循环 // 列表循环
if (nextIndex >= episodes.length) { if (nextIndex >= episodes.length) {
if (platRepeat == PlayRepeat.listCycle) { if (platRepeat == PlayRepeat.listCycle) {