feat: up投稿播放全部

This commit is contained in:
guozhigq
2024-11-02 01:51:26 +08:00
parent 3209bde290
commit a69a27cdc4
6 changed files with 126 additions and 19 deletions

View File

@ -516,4 +516,34 @@ class UserHttp {
};
}
}
// 解析up投稿
static Future parseUpArchiveVideo({
required int mid,
required int oid,
required String bvid,
String sortField = 'pubtime',
}) async {
var res = await Request().get(
'https://www.bilibili.com/list/$mid',
data: {
'oid': oid,
'bvid': bvid,
'sort_field': sortField,
},
);
String scriptContent =
extractScriptContents(parse(res.data).body!.outerHtml)[0];
int startIndex = scriptContent.indexOf('{');
int endIndex = scriptContent.lastIndexOf('};');
String jsonContent = scriptContent.substring(startIndex, endIndex + 1);
// 解析JSON字符串为Map
Map<String, dynamic> jsonData = json.decode(jsonContent);
return {
'status': true,
'data': jsonData['resourceList']
.map<MediaVideoItemModel>((e) => MediaVideoItemModel.fromJson(e))
.toList()
};
}
}

View File

@ -1,14 +1,16 @@
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:pilipala/http/member.dart';
import 'package:pilipala/http/search.dart';
import 'package:pilipala/models/member/archive.dart';
import 'package:pilipala/utils/global_data_cache.dart';
import 'package:pilipala/utils/utils.dart';
class MemberArchiveController extends GetxController {
final ScrollController scrollController = ScrollController();
late int mid;
int pn = 1;
int count = 0;
RxInt count = 0.obs;
RxMap<String, String> currentOrder = <String, String>{}.obs;
RxList<Map<String, String>> orderList = [
{'type': 'pubdate', 'label': '最新发布'},
@ -50,11 +52,11 @@ class MemberArchiveController extends GetxController {
if (res['status']) {
if (type == 'init') {
archivesList.value = res['data'].list.vlist;
count.value = res['data'].page['count'];
}
if (type == 'onLoad') {
archivesList.addAll(res['data'].list.vlist);
}
count = res['data'].page['count'];
pn += 1;
}
isLoading.value = false;
@ -76,4 +78,29 @@ class MemberArchiveController extends GetxController {
Future onLoad() async {
getMemberArchive('onLoad');
}
Future toViewPlayAll() async {
final VListItemModel firstItem = archivesList.first;
final String bvid = firstItem.bvid!;
final int cid = await SearchHttp.ab2c(bvid: bvid);
final String heroTag = Utils.makeHeroTag(bvid);
late Map sortFieldMap = {
'pubdate': 'pubtime',
'click': 'play',
'fav': 'fav',
};
Get.toNamed(
'/video?bvid=${firstItem.bvid}&cid=$cid',
arguments: {
'videoItem': firstItem,
'heroTag': heroTag,
'sourceType': 'up_archive',
'oid': firstItem.aid,
'favTitle': '${firstItem.owner!.name!} - ${currentOrder['label']!}',
'favInfo': firstItem,
'count': count.value,
'sortField': sortFieldMap[currentOrder['type']],
},
);
}
}

View File

@ -135,6 +135,15 @@ class _MemberArchivePageState extends State<MemberArchivePage> {
),
],
),
floatingActionButton: Obx(
() => _memberArchivesController.count > 0
? FloatingActionButton.extended(
onPressed: _memberArchivesController.toViewPlayAll,
label: const Text('播放全部'),
icon: const Icon(Icons.playlist_play),
)
: const SizedBox(),
),
);
}
}

View File

@ -119,6 +119,7 @@ class VideoDetailController extends GetxController
List<MediaVideoItemModel> mediaList = <MediaVideoItemModel>[];
RxBool isWatchLaterVisible = false.obs;
RxString watchLaterTitle = ''.obs;
RxInt watchLaterCount = 0.obs;
@override
void onInit() {
@ -170,7 +171,7 @@ class VideoDetailController extends GetxController
sourceType.value = argMap['sourceType'] ?? 'normal';
isWatchLaterVisible.value =
sourceType.value == 'watchLater' || sourceType.value == 'fav';
['watchLater', 'fav', 'up_archive'].contains(sourceType.value);
if (sourceType.value == 'watchLater') {
watchLaterTitle.value = '稍后再看';
fetchMediaList();
@ -179,6 +180,11 @@ class VideoDetailController extends GetxController
watchLaterTitle.value = argMap['favTitle'];
queryFavVideoList();
}
if (sourceType.value == 'up_archive') {
watchLaterTitle.value = argMap['favTitle'];
watchLaterCount.value = argMap['count'];
queryArchiveVideoList();
}
tabCtr.addListener(() {
onTabChanged();
});
@ -585,7 +591,9 @@ class VideoDetailController extends GetxController
}
void toggeleWatchLaterVisible(bool val) {
if (sourceType.value == 'watchLater' || sourceType.value == 'fav') {
if (sourceType.value == 'watchLater' ||
sourceType.value == 'fav' ||
sourceType.value == 'up_archive') {
isWatchLaterVisible.value = !isWatchLaterVisible.value;
}
}
@ -616,8 +624,19 @@ class VideoDetailController extends GetxController
changeMediaList: changeMediaList,
panelTitle: watchLaterTitle.value,
bvid: bvid,
mediaId: Get.arguments['mediaId'],
mediaId: [
'watchLater',
'fav',
].contains(sourceType.value)
? Get.arguments['mediaId']
: Get.arguments['favInfo'].owner.mid,
hasMore: mediaList.length != Get.arguments['count'],
type: [
'watchLater',
'fav',
].contains(sourceType.value)
? 3
: 1,
);
});
replyReplyBottomSheetCtr?.closed.then((value) {
@ -667,6 +686,21 @@ class VideoDetailController extends GetxController
}
}
Future queryArchiveVideoList() async {
final Map argMap = Get.arguments;
var favInfo = argMap['favInfo'];
var sortField = argMap['sortField'];
var res = await UserHttp.parseUpArchiveVideo(
mid: favInfo.owner.mid,
oid: oid.value,
bvid: bvid,
sortField: sortField,
);
if (res['status']) {
mediaList = res['data'];
}
}
// 监听tabBarView切换
void onTabChanged() {
isWatchLaterVisible.value = tabCtr.index == 0;

View File

@ -783,7 +783,8 @@ class _VideoDetailPageState extends State<VideoDetailPage>
Obx(
() => Visibility(
visible: vdCtr.sourceType.value == 'watchLater' ||
vdCtr.sourceType.value == 'fav',
vdCtr.sourceType.value == 'fav' ||
vdCtr.sourceType.value == 'up_archive',
child: AnimatedPositioned(
duration: const Duration(milliseconds: 400),
curve: Curves.easeInOut,
@ -815,17 +816,21 @@ class _VideoDetailPageState extends State<VideoDetailPage>
child: Row(children: [
const Icon(Icons.playlist_play, size: 24),
const SizedBox(width: 10),
Text(
vdCtr.watchLaterTitle.value,
style: TextStyle(
color: Theme.of(context)
.colorScheme
.onSecondaryContainer,
fontWeight: FontWeight.bold,
letterSpacing: 0.2,
Expanded(
child: Text(
vdCtr.watchLaterTitle.value,
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: TextStyle(
color: Theme.of(context)
.colorScheme
.onSecondaryContainer,
fontWeight: FontWeight.bold,
letterSpacing: 0.2,
),
),
),
const Spacer(),
const SizedBox(width: 50),
const Icon(Icons.keyboard_arrow_up_rounded, size: 26),
]),
),

View File

@ -19,8 +19,9 @@ class MediaListPanel extends StatefulWidget {
this.changeMediaList,
this.panelTitle,
this.bvid,
this.mediaId,
required this.mediaId,
this.hasMore = false,
required this.type,
super.key,
});
@ -29,8 +30,9 @@ class MediaListPanel extends StatefulWidget {
final Function? changeMediaList;
final String? panelTitle;
final String? bvid;
final int? mediaId;
final int mediaId;
final bool hasMore;
final int type;
@override
State<MediaListPanel> createState() => _MediaListPanelState();
@ -59,8 +61,8 @@ class _MediaListPanelState extends State<MediaListPanel> {
void loadMore() async {
var res = await UserHttp.getMediaList(
type: 3,
bizId: widget.mediaId!,
type: widget.type,
bizId: widget.mediaId,
ps: 20,
oid: mediaList.last.id,
);