fix: parse live info

opt: items

Signed-off-by: bggRGjQaUbCoE <githubaccount56556@proton.me>
This commit is contained in:
bggRGjQaUbCoE
2025-04-30 13:01:47 +08:00
parent 77e4a30bc5
commit 23813eb224
9 changed files with 247 additions and 286 deletions

View File

@@ -31,82 +31,73 @@ class VideoCardHGrpc extends StatelessWidget {
final int aid = videoItem.smallCoverV5.base.args.aid.toInt(); final int aid = videoItem.smallCoverV5.base.args.aid.toInt();
String type = 'video'; String type = 'video';
final String heroTag = Utils.makeHeroTag(aid); final String heroTag = Utils.makeHeroTag(aid);
return Stack( return InkWell(
clipBehavior: Clip.none, borderRadius: BorderRadius.circular(12),
children: [ onLongPress: () => imageSaveDialog(
Semantics( title: videoItem.smallCoverV5.base.title,
excludeSemantics: true, cover: videoItem.smallCoverV5.base.cover,
child: InkWell( ),
borderRadius: BorderRadius.circular(12), onTap: () async {
onLongPress: () => imageSaveDialog( if (type == 'ketang') {
title: videoItem.smallCoverV5.base.title, SmartDialog.showToast('课堂视频暂不支持播放');
cover: videoItem.smallCoverV5.base.cover, return;
), }
onTap: () async { try {
if (type == 'ketang') { PiliScheme.routePushFromUrl(videoItem.smallCoverV5.base.uri);
SmartDialog.showToast('课堂视频暂不支持播放'); } catch (err) {
return; SmartDialog.showToast(err.toString());
} }
try { },
PiliScheme.routePushFromUrl(videoItem.smallCoverV5.base.uri); child: LayoutBuilder(
} catch (err) { builder: (BuildContext context, BoxConstraints boxConstraints) {
SmartDialog.showToast(err.toString()); return Row(
} mainAxisAlignment: MainAxisAlignment.start,
}, crossAxisAlignment: CrossAxisAlignment.start,
child: LayoutBuilder( children: <Widget>[
builder: (BuildContext context, BoxConstraints boxConstraints) { AspectRatio(
return Row( aspectRatio: StyleString.aspectRatio,
mainAxisAlignment: MainAxisAlignment.start, child: LayoutBuilder(
crossAxisAlignment: CrossAxisAlignment.start, builder:
children: <Widget>[ (BuildContext context, BoxConstraints boxConstraints) {
AspectRatio( final double maxWidth = boxConstraints.maxWidth;
aspectRatio: StyleString.aspectRatio, final double maxHeight = boxConstraints.maxHeight;
child: LayoutBuilder( return Stack(
builder: (BuildContext context, clipBehavior: Clip.none,
BoxConstraints boxConstraints) { children: [
final double maxWidth = boxConstraints.maxWidth; Hero(
final double maxHeight = boxConstraints.maxHeight; tag: heroTag,
return Stack( child: NetworkImgLayer(
clipBehavior: Clip.none, src: videoItem.smallCoverV5.base.cover,
children: [ width: maxWidth,
Hero( height: maxHeight,
tag: heroTag, ),
child: NetworkImgLayer( ),
src: videoItem.smallCoverV5.base.cover, if (videoItem.smallCoverV5.coverRightText1.isNotEmpty)
width: maxWidth, PBadge(
height: maxHeight, text: Utils.timeFormat(
), videoItem.smallCoverV5.coverRightText1),
), right: 6.0,
if (videoItem bottom: 6.0,
.smallCoverV5.coverRightText1.isNotEmpty) type: 'gray',
PBadge( ),
text: Utils.timeFormat( if (type != 'video')
videoItem.smallCoverV5.coverRightText1), PBadge(
right: 6.0, text: type,
bottom: 6.0, left: 6.0,
type: 'gray', bottom: 6.0,
), type: 'primary',
if (type != 'video') ),
PBadge( ],
text: type, );
left: 6.0, },
bottom: 6.0, ),
type: 'primary', ),
), const SizedBox(width: 10),
], videoContent(context),
); ],
}, );
), },
), ),
const SizedBox(width: 10),
videoContent(context),
],
);
},
),
),
),
],
); );
} }

View File

@@ -55,57 +55,49 @@ class VideoCardVMemberHome extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Stack( return Card(
clipBehavior: Clip.none, clipBehavior: Clip.hardEdge,
children: [ margin: EdgeInsets.zero,
Semantics( child: InkWell(
excludeSemantics: true, onTap: () => onPushDetail(Utils.makeHeroTag(videoItem.bvid)),
child: Card( onLongPress: () => imageSaveDialog(
clipBehavior: Clip.hardEdge, title: videoItem.title,
margin: EdgeInsets.zero, cover: videoItem.cover,
child: InkWell( ),
onTap: () => onPushDetail(Utils.makeHeroTag(videoItem.bvid)), child: Column(
onLongPress: () => imageSaveDialog( crossAxisAlignment: CrossAxisAlignment.start,
title: videoItem.title, children: [
cover: videoItem.cover, AspectRatio(
), aspectRatio: StyleString.aspectRatio,
child: Column( child: LayoutBuilder(
crossAxisAlignment: CrossAxisAlignment.start, builder: (context, boxConstraints) {
children: [ double maxWidth = boxConstraints.maxWidth;
AspectRatio( double maxHeight = boxConstraints.maxHeight;
aspectRatio: StyleString.aspectRatio, return Stack(
child: LayoutBuilder( clipBehavior: Clip.none,
builder: (context, boxConstraints) { children: [
double maxWidth = boxConstraints.maxWidth; NetworkImgLayer(
double maxHeight = boxConstraints.maxHeight; src: videoItem.cover,
return Stack( width: maxWidth,
clipBehavior: Clip.none, height: maxHeight,
children: [ ),
NetworkImgLayer( if ((videoItem.duration ?? -1) > 0)
src: videoItem.cover, PBadge(
width: maxWidth, bottom: 6,
height: maxHeight, right: 7,
), size: 'small',
if ((videoItem.duration ?? -1) > 0) type: 'gray',
PBadge( text: Utils.timeFormat(videoItem.duration),
bottom: 6, )
right: 7, ],
size: 'small', );
type: 'gray', },
text: Utils.timeFormat(videoItem.duration),
)
],
);
},
),
),
videoContent(context, videoItem)
],
), ),
), ),
), videoContent(context, videoItem)
],
), ),
], ),
); );
} }
} }

View File

@@ -16,11 +16,16 @@ class RoomInfoH5Model {
Map? blockInfo; Map? blockInfo;
RoomInfoH5Model.fromJson(Map<String, dynamic> json) { RoomInfoH5Model.fromJson(Map<String, dynamic> json) {
roomInfo = RoomInfo.fromJson(json['room_info']); roomInfo =
anchorInfo = AnchorInfo.fromJson(json['anchor_info']); json['room_info'] == null ? null : RoomInfo.fromJson(json['room_info']);
anchorInfo = json['anchor_info'] == null
? null
: AnchorInfo.fromJson(json['anchor_info']);
isRoomFeed = json['is_room_feed']; isRoomFeed = json['is_room_feed'];
watchedShow = json['watched_show']; watchedShow = json['watched_show'];
likeInfoV3 = LikeInfoV3.fromJson(json['like_info_v3']); likeInfoV3 = json['like_info_v3'] == null
? null
: LikeInfoV3.fromJson(json['like_info_v3']);
blockInfo = json['block_info']; blockInfo = json['block_info'];
} }
} }
@@ -82,15 +87,18 @@ class RoomInfo {
class AnchorInfo { class AnchorInfo {
AnchorInfo({ AnchorInfo({
this.baseInfo, this.baseInfo,
this.relationInfo, // this.relationInfo,
}); });
BaseInfo? baseInfo; BaseInfo? baseInfo;
RelationInfo? relationInfo; // RelationInfo? relationInfo;
AnchorInfo.fromJson(Map<String, dynamic> json) { AnchorInfo.fromJson(Map<String, dynamic> json) {
baseInfo = BaseInfo.fromJson(json['base_info']); baseInfo =
relationInfo = RelationInfo.fromJson(json['relation_info']); json['base_info'] == null ? null : BaseInfo.fromJson(json['base_info']);
// relationInfo = json['relation_info'] == null
// ? null
// : RelationInfo.fromJson(json['relation_info']);
} }
} }

View File

@@ -43,20 +43,13 @@ class BangumiCardVMemberHome extends StatelessWidget {
child: AspectRatio( child: AspectRatio(
aspectRatio: 0.75, aspectRatio: 0.75,
child: LayoutBuilder(builder: (context, boxConstraints) { child: LayoutBuilder(builder: (context, boxConstraints) {
final double maxWidth = boxConstraints.maxWidth; return Hero(
final double maxHeight = boxConstraints.maxHeight; tag: heroTag,
return Stack( child: NetworkImgLayer(
clipBehavior: Clip.none, src: bangumiItem.cover,
children: [ width: boxConstraints.maxWidth,
Hero( height: boxConstraints.maxHeight,
tag: heroTag, ),
child: NetworkImgLayer(
src: bangumiItem.cover,
width: maxWidth,
height: maxHeight,
),
),
],
); );
}), }),
), ),

View File

@@ -30,7 +30,7 @@ class LiveRoomController extends GetxController {
RxBool volumeOff = false.obs; RxBool volumeOff = false.obs;
PlPlayerController plPlayerController = PlPlayerController plPlayerController =
PlPlayerController.getInstance(videoType: 'live'); PlPlayerController.getInstance(videoType: 'live');
Rx<RoomInfoH5Model> roomInfoH5 = RoomInfoH5Model().obs; Rx<RoomInfoH5Model?> roomInfoH5 = Rx<RoomInfoH5Model?>(null);
RxList<dynamic> messages = [].obs; RxList<dynamic> messages = [].obs;
RxBool disableAutoScroll = false.obs; RxBool disableAutoScroll = false.obs;
@@ -50,6 +50,7 @@ class LiveRoomController extends GetxController {
void onInit() { void onInit() {
super.onInit(); super.onInit();
roomId = int.parse(Get.parameters['roomid']!); roomId = int.parse(Get.parameters['roomid']!);
queryLiveInfoH5();
if (Accounts.main.isLogin && !MineController.anonymity.value) { if (Accounts.main.isLogin && !MineController.anonymity.value) {
VideoHttp.roomEntryAction(roomId: roomId); VideoHttp.roomEntryAction(roomId: roomId);
} }
@@ -131,7 +132,6 @@ class LiveRoomController extends GetxController {
heroTag, heroTag,
); );
} }
return res;
} }
LiveMessageStream? msgStream; LiveMessageStream? msgStream;

View File

@@ -2,6 +2,7 @@ import 'dart:async';
import 'dart:io'; import 'dart:io';
import 'dart:ui'; import 'dart:ui';
import 'package:PiliPlus/models/live/room_info_h5.dart';
import 'package:PiliPlus/pages/live_room/send_dm_panel.dart'; import 'package:PiliPlus/pages/live_room/send_dm_panel.dart';
import 'package:PiliPlus/pages/live_room/widgets/chat.dart'; import 'package:PiliPlus/pages/live_room/widgets/chat.dart';
import 'package:PiliPlus/pages/live_room/widgets/header_control.dart'; import 'package:PiliPlus/pages/live_room/widgets/header_control.dart';
@@ -36,7 +37,6 @@ class _LiveRoomPageState extends State<LiveRoomPage>
late final int _roomId; late final int _roomId;
late final LiveRoomController _liveRoomController; late final LiveRoomController _liveRoomController;
late final PlPlayerController plPlayerController; late final PlPlayerController plPlayerController;
late Future? _futureBuilder;
late Future? _futureBuilderFuture; late Future? _futureBuilderFuture;
bool get isFullScreen => plPlayerController.isFullScreen.value; bool get isFullScreen => plPlayerController.isFullScreen.value;
@@ -113,7 +113,6 @@ class _LiveRoomPageState extends State<LiveRoomPage>
} }
void videoSourceInit() { void videoSourceInit() {
_futureBuilder = _liveRoomController.queryLiveInfoH5();
plPlayerController = _liveRoomController.plPlayerController; plPlayerController = _liveRoomController.plPlayerController;
} }
@@ -222,14 +221,14 @@ class _LiveRoomPageState extends State<LiveRoomPage>
: Positioned.fill( : Positioned.fill(
child: Opacity( child: Opacity(
opacity: 0.6, opacity: 0.6,
child: _liveRoomController.roomInfoH5.value.roomInfo child: _liveRoomController.roomInfoH5.value?.roomInfo
?.appBackground?.isNotEmpty == ?.appBackground?.isNotEmpty ==
true true
? CachedNetworkImage( ? CachedNetworkImage(
fit: BoxFit.cover, fit: BoxFit.cover,
width: Get.width, width: Get.width,
height: Get.height, height: Get.height,
imageUrl: _liveRoomController.roomInfoH5.value imageUrl: _liveRoomController.roomInfoH5.value!
.roomInfo!.appBackground!.http2https, .roomInfo!.appBackground!.http2https,
) )
: Image.asset( : Image.asset(
@@ -367,62 +366,54 @@ class _LiveRoomPageState extends State<LiveRoomPage>
foregroundColor: Colors.white, foregroundColor: Colors.white,
toolbarHeight: isFullScreen ? 0 : null, toolbarHeight: isFullScreen ? 0 : null,
titleTextStyle: TextStyle(color: Colors.white), titleTextStyle: TextStyle(color: Colors.white),
title: FutureBuilder( title: Obx(
future: _futureBuilder, () {
builder: (context, snapshot) { return _liveRoomController.roomInfoH5.value == null
if (snapshot.data == null) { ? const SizedBox.shrink()
return const SizedBox.shrink(); : Row(
} children: [
Map data = snapshot.data as Map; GestureDetector(
if (data['status']) { onTap: () {
return Obx( dynamic uid = _liveRoomController
() => Row( .roomInfoH5.value!.roomInfo?.uid;
children: [ Get.toNamed(
GestureDetector( '/member?mid=$uid',
onTap: () { arguments: {
dynamic uid = 'heroTag': Utils.makeHeroTag(uid),
_liveRoomController.roomInfoH5.value.roomInfo?.uid; },
Get.toNamed( );
'/member?mid=$uid', },
arguments: { child: NetworkImgLayer(
'heroTag': Utils.makeHeroTag(uid), width: 34,
}, height: 34,
); type: 'avatar',
}, src: _liveRoomController
child: NetworkImgLayer( .roomInfoH5.value!.anchorInfo!.baseInfo!.face,
width: 34,
height: 34,
type: 'avatar',
src: _liveRoomController
.roomInfoH5.value.anchorInfo!.baseInfo!.face,
),
),
const SizedBox(width: 10),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
_liveRoomController
.roomInfoH5.value.anchorInfo!.baseInfo!.uname!,
style: const TextStyle(fontSize: 14),
), ),
const SizedBox(height: 1), ),
if (_liveRoomController.roomInfoH5.value.watchedShow != const SizedBox(width: 10),
null) Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text( Text(
_liveRoomController.roomInfoH5.value _liveRoomController
.watchedShow!['text_large'] ?? .roomInfoH5.value!.anchorInfo!.baseInfo!.uname!,
'', style: const TextStyle(fontSize: 14),
style: const TextStyle(fontSize: 12),
), ),
], const SizedBox(height: 1),
), if (_liveRoomController
], .roomInfoH5.value!.watchedShow !=
), null)
); Text(
} else { _liveRoomController.roomInfoH5.value!
return const SizedBox.shrink(); .watchedShow!['text_large'] ??
} '',
style: const TextStyle(fontSize: 12),
),
],
),
],
);
}, },
), ),
actions: [ actions: [
@@ -452,42 +443,39 @@ class _LiveRoomPageState extends State<LiveRoomPage>
], ],
), ),
), ),
PopupMenuItem( if (_liveRoomController.roomInfoH5.value != null)
onTap: () { PopupMenuItem(
try { onTap: () {
PageUtils.pmShare( try {
this.context, RoomInfoH5Model roomInfo =
content: { _liveRoomController.roomInfoH5.value!;
"cover": _liveRoomController PageUtils.pmShare(
.roomInfoH5.value.roomInfo!.cover!, this.context,
"sourceID": _liveRoomController.roomId.toString(), content: {
"title": _liveRoomController "cover": roomInfo.roomInfo!.cover!,
.roomInfoH5.value.roomInfo!.title!, "sourceID": _liveRoomController.roomId.toString(),
"url": "title": roomInfo.roomInfo!.title!,
"https://live.bilibili.com/${_liveRoomController.roomId}", "url":
"authorID": _liveRoomController "https://live.bilibili.com/${_liveRoomController.roomId}",
.roomInfoH5.value.roomInfo!.uid "authorID": roomInfo.roomInfo!.uid.toString(),
.toString(), "source": "直播",
"source": "直播", "desc": roomInfo.roomInfo!.title!,
"desc": _liveRoomController "author": roomInfo.anchorInfo!.baseInfo!.uname,
.roomInfoH5.value.roomInfo!.title!, },
"author": _liveRoomController );
.roomInfoH5.value.anchorInfo!.baseInfo!.uname, } catch (e) {
}, SmartDialog.showToast(e.toString());
); }
} catch (e) { },
SmartDialog.showToast(e.toString()); child: const Row(
} mainAxisSize: MainAxisSize.min,
}, children: [
child: const Row( Icon(Icons.forward_to_inbox, size: 19),
mainAxisSize: MainAxisSize.min, SizedBox(width: 10),
children: [ Text('分享至消息'),
Icon(Icons.forward_to_inbox, size: 19), ],
SizedBox(width: 10), ),
Text('分享至消息'),
],
), ),
),
], ],
), ),
], ],

View File

@@ -45,15 +45,10 @@ class MemberFavItem extends StatelessWidget {
aspectRatio: StyleString.aspectRatio, aspectRatio: StyleString.aspectRatio,
child: LayoutBuilder( child: LayoutBuilder(
builder: (context, boxConstraints) { builder: (context, boxConstraints) {
return Stack( return NetworkImgLayer(
clipBehavior: Clip.none, src: item['cover'],
children: [ width: boxConstraints.maxWidth,
NetworkImgLayer( height: boxConstraints.maxHeight,
src: item['cover'],
width: boxConstraints.maxWidth,
height: boxConstraints.maxHeight,
),
],
); );
}, },
), ),

View File

@@ -85,47 +85,42 @@ class SubVideoCardH extends StatelessWidget {
Widget videoContent(context) { Widget videoContent(context) {
return Expanded( return Expanded(
child: Stack( child: Column(
clipBehavior: Clip.none, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Column( Expanded(
crossAxisAlignment: CrossAxisAlignment.start, child: Text(
'${videoItem.title}',
textAlign: TextAlign.start,
style: const TextStyle(
letterSpacing: 0.3,
),
maxLines: 2,
overflow: TextOverflow.ellipsis,
),
),
Text(
Utils.dateFormat(videoItem.pubtime),
style: TextStyle(
fontSize: 12,
color: Theme.of(context).colorScheme.outline,
),
),
const SizedBox(height: 3),
Row(
children: [ children: [
Expanded( StatView(
child: Text( context: context,
'${videoItem.title}', theme: 'gray',
textAlign: TextAlign.start, value: Utils.numFormat(videoItem.cntInfo?['play']),
style: const TextStyle(
letterSpacing: 0.3,
),
maxLines: 2,
overflow: TextOverflow.ellipsis,
),
), ),
Text( const SizedBox(width: 8),
Utils.dateFormat(videoItem.pubtime), StatDanMu(
style: TextStyle( context: context,
fontSize: 12, theme: 'gray',
color: Theme.of(context).colorScheme.outline, value: Utils.numFormat(videoItem.cntInfo?['danmaku']),
),
),
const SizedBox(height: 3),
Row(
children: [
StatView(
context: context,
theme: 'gray',
value: Utils.numFormat(videoItem.cntInfo?['play']),
),
const SizedBox(width: 8),
StatDanMu(
context: context,
theme: 'gray',
value: Utils.numFormat(videoItem.cntInfo?['danmaku']),
),
const Spacer(),
],
), ),
const Spacer(),
], ],
), ),
], ],

View File

@@ -732,7 +732,6 @@ class _PLVideoPlayerState extends State<PLVideoPlayer>
return Stack( return Stack(
fit: StackFit.passthrough, fit: StackFit.passthrough,
key: _playerKey, key: _playerKey,
clipBehavior: Clip.none,
children: <Widget>[ children: <Widget>[
Obx( Obx(
() => Video( () => Video(